﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Client.Test
{
    /// <summary>
    /// Interaction logic for FrmTest_MessageBox.xaml
    /// </summary>
    public partial class FrmTest_MessageBox : Window
    {
        private string _LongMsg;
        public string LongMsg
        {
            get
            {
                if (_LongMsg.IsNullOrEmpty())
                {
                    string base64Str = "dXNpbmcgU3lzdGVtOw0KdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7DQp1c2luZyBTeXN0ZW0uQ29tcG9uZW50TW9kZWw7DQp1c2luZyBTeXN0ZW0uRHJhd2luZzsNCnVzaW5nIFN5c3RlbS5MaW5xOw0KdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOw0KdXNpbmcgU3lzdGVtLlRleHQ7DQp1c2luZyBTeXN0ZW0uV2luZG93czsNCnVzaW5nIFN5c3RlbS5XaW5kb3dzLkNvbnRyb2xzOw0KdXNpbmcgU3lzdGVtLldpbmRvd3MuRGF0YTsNCnVzaW5nIFN5c3RlbS5XaW5kb3dzLkRvY3VtZW50czsNCnVzaW5nIFN5c3RlbS5XaW5kb3dzLklucHV0Ow0KdXNpbmcgU3lzdGVtLldpbmRvd3MuTWVkaWE7DQp1c2luZyBTeXN0ZW0uV2luZG93cy5NZWRpYS5BbmltYXRpb247DQp1c2luZyBTeXN0ZW0uV2luZG93cy5NZWRpYS5JbWFnaW5nOw0KdXNpbmcgU3lzdGVtLldpbmRvd3MuU2hhcGVzOw0KDQpuYW1lc3BhY2UgV1BGQ29udHJvbHMNCnsNCiAgICAvLyBWIDEuMC45IC0gMjAyMi0wNy0yNSAxNTozMDo1Ng0KICAgIC8vIDEg56aB5q2i5L+h5oGv5Ye6546w5qiq5ZCR5rua5Yqo5p2hDQogICAgLy8gMiDkv67lpI0gRXhwYW5kIOa7muWKqOadoeagt+W8j+mXrumimA0KICAgIC8vIDMg5Li6IFNob3cg5Yqg5LiK5Zue6LCD5Ye95pWwLCDov5Tlm57nlKjmiLfpgInkuK3nmoQgTWVzc2FnZUJveFJlc3VsdA0KICAgIC8vIA0KICAgIC8vIFYgMS4wLjggLSAyMDIxLTEwLTI5IDE2OjA1OjA2DQogICAgLy8gMSDkvJjljJbliJvlu7rmjInpkq7pgLvovpENCiAgICAvLyAyIOS8mOWMluaYvuekuueVjOmdouaXtiDpgInkuK0g6buY6K6k5oyJ6ZKuIOmAu+i+kQ0KICAgIC8vIDMg6YeN5paw5pW055CG5ZCE5Liq6Z2Z5oCB5Yib5bu65pa55rOVICgg5Yqg5LiKIGRlZmF1bHRSZXN1bHQg5Y+C5pWwIOeUqOS6juaMh+Wumum7mOiupOe7k+aenCApDQogICAgLy8NCiAgICAvLyBWIDEuMC43IC0gMjAyMS0xMC0yOCAxNToxNTo0MA0KICAgIC8vIDEg55WM6Z2i5paw5aKeIEV4dHJhQ29udGVudCDnsbvlnovkuLogQ29udGVudENvbnRyb2wsIOWPr+S7peaMieimgeaxguS8oOWFpSBDb250ZW50Q290cm9sICgg5b+F6aG75piv5a6e546wIElEYXRhRXJyb3JJbmZvIOaOpeWPoywg54K55Ye744CQ56Gu6K6k44CR5oyJ6ZKu5pe25Lya5qCh6aqMIElEYXRhRXJyb3JJbmZvLkVycm9yIOWxnuaApyApDQogICAgLy8g5Y+v5Lul5b+r5o235Zyw6Ieq5a6a5LmJ5LiA5Lqb566A5Y2V55qE6L6T5YWlIOS+i+WmgiDotKblj7flr4bnoIEgLyDmiZPljbDmlbDph48g562J6L6T5YWl5qGGDQogICAgLy8gMiDmjInpkq7moLflvI/kvJjljJYsIOS9v+eUqCBDbGllbnQuQ29tcG9uZW50cy5CdXR0b25CYXNlDQogICAgLy8gMyDkvJjljJbmoLflvI8sIOWFqOmDqOS9v+eUqCBLZXkg55qE5pa55byP6LCD55So5qC35byPLCDku47ogIzlh4/lsJHnlLHkuo7moLflvI/nmoTlkJHkuIvlu7bnlLPlr7zoh7TlkITnp43mgKrlvILnmoTmoLflvI/pl67popggKCDkvovlpoIgRGF0ZVBpY2tlciDnmoTmoLflvI/ooqsg5Y6f5YWIIE1lc3NhZ2VCb3gg6LWE5rqQ5Lit55qEIEJ1dHRvbiBJbWFnZSDmoLflvI/mkJ7liLDkubHmmZLpmoYgKQ0KICAgIC8vIDQg5o+Q5L6b6buY6K6k5oyJ6ZKu57uZ56iL5bqP5ZGY6YCJ5oupDQogICAgLy8gDQogICAgLy8gViAxLjAuNiAtIDIwMjEtMDgtMjYgMDk6MTU6MTcNCiAgICAvLyDkvJjljJbkvKDlhaXlvZPliY3nqpflj6Plj4LmlbDkuLrnqbrlgLzml7YsIOiOt+WPliBBcHBsaWNhdGlvbi5DdXJyZW50LldpbmRvd3Mg5LitIElzQWN0aXZlID0gdHJ1ZSDnmoTpppbkuKogV2luZG93DQogICAgLy8gDQogICAgLy8gViAxLjAuNSAtIDIwMjEtMDctMjUgMTE6NTU6NTkNCiAgICAvLyDorr7nva7pu5jorqQgV2luZG93U3RhcnR1cExvY2F0aW9uIOS4uiBDZW50ZXJPd25lcg0KICAgIC8vIA0KICAgIC8vIFYgMS4wLjQgLSAyMDIxLTA2LTI0IDE2OjU1OjQ2DQogICAgLy8g5LyY5YyW6Ieq5Yqo5YWz6Zet55u45YWz6YC76L6R77ya5Zyo6Ieq5Yqo5YWz6Zet56qX5Y+j5YmN56Gu5L+dIElzRm9jdXNlZCDkuLogdHJ1ZQ0KICAgIC8vIA0KICAgIC8vIFYgMS4wLjMgLSAyMDIxLTA2LTI0IDEzOjUxOjQ4DQogICAgLy8gMS4g5aKe5YqgIGF1dG9DbG9zZVRpbWVTcGFuIO+8iOWAkuiuoeaXtuiHquWKqOWFs+mXre+8iQ0KICAgIC8vIDIuIOS8mOWMliBTaG93RXJyb3Ig5pi+56S66K+m57uG5byC5bi45L+h5oGv6YC76L6R77yIIOWwhiBIb3dlc0RPTU8uVXRpbHMg55qEIEV4Y2VwdGlvbi5HZXRJbmZvIOmAu+i+keaQrOenu+WIsOatpOWkhCDvvIkNCiAgICAvLyANCiAgICAvLyBWIDEuMC4yIC0gMjAyMS0wNi0yMyAxMjoxNjoxNQ0KICAgIC8vIOS4uuS6huWMuuWIhiBTaG93IOS4jiBTaG93RGlhbG9n77yM5paw5aKeIFNob3dEaWFsb2fmlrnms5XvvIzkv67mlLnljp/mnaXnmoQgU2hvdyDmlrnms5UgbWVzc2FnZUJveC5TaG93RGlhbG9nKCk7ID09PiBtZXNzYWdlQm94LlNob3coKTsNCiAgICAvLyANCiAgICAvLyBWIDEuMC4xIC0gMjAyMS0wMy0yMSAxNzo1NToyMg0KICAgIC8vIOW8g+eUqFN5c3RlbS5XaW5kb3dzLkZvcm1zLlNjcmVlbi5QcmltYXJ5U2NyZWVuLldvcmtpbmdBcmVh55qE5pa55byP6I635Y+W5bGP5bmV5YiG6L6o546HLA0KICAgIC8vIOaUueeUqFNjcmVlblV0aWxzKCDku44gZ2l0aHViIOS4iuiOt+WPlueahOW8gOa6kOmhueebriwg5bey5bWM5YWl5YiwIFdQRkNvbnRyb2xzICkNCiAgICAvLyANCiAgICAvLyBWIDEuMC4wIC0gMjAyMS0wMy0yMSAxNDozNjo1OA0KICAgIC8vIOaUueWGmSDpobnnm64NCiAgICAvLyDmlbTnkIbku6PnoIEsIOW5tuWvueS7peS4i+WHoOeCueS9nOS6huS8mOWMlg0KICAgIC8vIDEuIOW9k+WQq+acieivpuaDheS/oeaBr+aXtiwg5Y+v5Lul5L2/55SoIEdyaWRTcGxpdHRlciDkuIrkuIvmi5bliqjmnaXmlLnlj5gg5Li75L+h5oGv5LiO6K+m5oOF5L+h5oGv55qE5pi+56S656m66Ze05aSn5bCPDQogICAgLy8gMi4gVXNlckRlZmluZUZvbnRTaXplRGljdCAoIOeUqOaIt+iHquWumuS5iSBGb250U2l6ZSDlrZflhbggKSwg55So5p2l6Ieq5a6a5LmJ5p+Q5Lqb56qX5L2T5LiL5a2X5L2T55qE6Ieq5a6a5LmJ5aSn5bCPDQogICAgLy8gMy4g6YeH55So6K+75Y+W5b2T5YmN6K6h566X5py655qEIFdvcmtBcmVhIOeahOmVv+WuveWDj+aVsCwg5p2l6K6+572u56qX5L2T5YaF5ZCE5Liq5Zyw5pa55a+55bqU55qE5pyA5aSn5a695bqm5oiW5pyA5aSn6auY5bqmDQogICAgLy8gNC4gVUnkvJjljJYgKCDph43mlLnnu5PmnoQsIOS8mOWMluaMiemSruS/oeaBryjlv6vmjbfplK7mjInpkq7liqDkuIvliJLnur8pIOetiSApDQoNCiAgICAvLy8gPHN1bW1hcnk+DQogICAgLy8vIDxwYXJhPumHjeaWsOWwgeijheeahCBNZXNzYWdlQm94PC9wYXJhPg0KICAgIC8vLyA8cGFyYT5Db25maXJtIOS4jiBRdWVzdGlvbiDnmoTljLrliKs6IENvbmZpcm0gW09rLCBDYW5jZWxdOyBRdWVzdGlvbiBbWWVzLCBObywgQ2FuY2VsXTwvcGFyYT4NCiAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgIHB1YmxpYyBwYXJ0aWFsIGNsYXNzIE1lc3NhZ2VCb3ggOiBJTm90aWZ5UHJvcGVydHlDaGFuZ2VkDQogICAgew0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDnlKjmiLfoh6rlrprkuYkgRm9udFNpemUg5a2X5YW4DQogICAgICAgIC8vLyDnqIvluo9TdGFydFVw5pe2LCDlupTor6XlkJHmnKzlsZ7mgKfmjIflrprpnIDopoHoh6rlrprkuYlGb250U2l6ZeeahOeql+S9k0Z1bGxOYW1lDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHByaXZhdGUgc3RhdGljIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkRpY3Rpb25hcnk8c3RyaW5nLCBkb3VibGU+IFVzZXJEZWZpbmVGb250U2l6ZURpY3QgeyBnZXQ7IHNldDsgfSA9IG5ldyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5EaWN0aW9uYXJ5PHN0cmluZywgZG91YmxlPigpOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPuiuvue9ruWtl+S9k+Wkp+WwjzwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPuW9kyBPd25lciDlnKjlrZflhbjkuK0sIOeql+S9k+Wtl+S9k+Wkp+Wwj+i3n+maj+iHquWumuS5iTwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJrZXkiPumcgOimgeiuvue9ruiHquWumuS5ieeql+S9k+WQjeensCAoV2luZG93KUZybS5Ub1N0cmluZygpPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJ2YWx1ZSI+5a2X5L2T5aSn5bCPPC9wYXJhbT4NCiAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIEFkZFVzZXJEZWZpbmVGb250U2l6ZShzdHJpbmcga2V5LCBkb3VibGUgdmFsdWUpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChVc2VyRGVmaW5lRm9udFNpemVEaWN0LkNvbnRhaW5zS2V5KGtleSkgPT0gZmFsc2UpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgVXNlckRlZmluZUZvbnRTaXplRGljdC5BZGQoa2V5LCB2YWx1ZSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgVXNlckRlZmluZUZvbnRTaXplRGljdFtrZXldID0gdmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBib29sIG1BbmltYXRpb25SYW4geyBnZXQ7IHNldDsgfSA9IGZhbHNlOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOeCueWHuyBNZXNzYWdlQm94LlNob3cg5oyJ6ZKu5ZCOLCDmiafooYznmoTlm57osIPlh73mlbANCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBPbkFjdGlvbiB7IGdldDsgc2V0OyB9DQogICAgICAgIA0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT7mnoTpgKDlh73mlbA8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3duZXIiPlRoZSBtZXNzYWdlIGJveCdzIHBhcmVudCB3aW5kb3c8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImJ1dHRvbiI+QnV0dG9uczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaWNvbiI+SWNvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4gICAgICAgIA0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBZZXM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9wdGlvbnMiPk1pc2Mgb3B0aW9uczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib25BY3Rpb24iPuWbnuiwg+WHveaVsCwg5omn6KGMIFNob3cg5pa55rOV55So5oi354K55Ye75oyJ6ZKu5pe25Lya5omn6KGM5Zue6LCD5Ye95pWwPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICBwdWJsaWMgTWVzc2FnZUJveChXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscywgTWVzc2FnZUJveEJ1dHRvbiBidXR0b24sIE1lc3NhZ2VCb3hJbWFnZSBpY29uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQsIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMsIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIEluaXRpYWxpemVDb21wb25lbnQoKTsNCg0KICAgICAgICAgICAgdGhpcy5XaW5kb3dTdGFydHVwTG9jYXRpb24gPSBXaW5kb3dTdGFydHVwTG9jYXRpb24uQ2VudGVyT3duZXI7DQoNCiAgICAgICAgICAgIHRyeQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuT3duZXIgPSBvd25lciA/PyBnZXRDdXJyZW50V2luZG93KCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuT3duZXIgPSBBcHBsaWNhdGlvbi5DdXJyZW50Lk1haW5XaW5kb3c7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIOeUqOaIt+iHquWumuS5iSBGb250U2l6ZSDlrZflhbgNCiAgICAgICAgICAgIGlmIChVc2VyRGVmaW5lRm9udFNpemVEaWN0LlRyeUdldFZhbHVlKHRoaXMuT3duZXIuVG9TdHJpbmcoKSwgb3V0IGRvdWJsZSB1c2VyRGVmaW5lRm9udFNpemUpKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuRm9udFNpemUgPSB1c2VyRGVmaW5lRm9udFNpemU7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIOiuvue9riBGb250U2l6ZQ0KICAgICAgICAgICAgdGhpcy5NZXNzYWdlVGV4dC5Gb250U2l6ZSA9IHRoaXMuRm9udFNpemU7DQoNCiAgICAgICAgICAgIGlmICh1c2VyRGVmaW5lRm9udFNpemUgPiAyNSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvLyDorr7nva4gQnV0dG9uUGFuZWwg55qEIEZvbnRTaXplICgg55Sx5LqOU3RhY2tQYW5lbOaXoEZvbnRTaXplLCDkvb/nlKhTdHlsZei/m+ihjOiuvue9riApDQogICAgICAgICAgICAgICAgU3R5bGUgc3R5bGUgPSBuZXcgU3R5bGUoKTsNCiAgICAgICAgICAgICAgICBzdHlsZS5TZXR0ZXJzLkFkZChuZXcgU2V0dGVyKEZvbnRTaXplUHJvcGVydHksIHRoaXMuRm9udFNpemUgKiAwLjdkKSk7DQogICAgICAgICAgICAgICAgdGhpcy5CdXR0b25zUGFuZWwuU3R5bGUgPSBzdHlsZTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgdGhpcy5DcmVhdGVCdXR0b25zKGJ1dHRvbiwgZGVmYXVsdFJlc3VsdCk7DQogICAgICAgICAgICB0aGlzLkNyZWF0ZUltYWdlKGljb24pOw0KICAgICAgICAgICAgdGhpcy5BcHBseU9wdGlvbnMob3B0aW9ucyk7DQoNCiAgICAgICAgICAgIC8vIE1lc3NhZ2UNCiAgICAgICAgICAgIHRoaXMuTWVzc2FnZVRleHQuVGV4dCA9IG1lc3NhZ2U7DQoNCiAgICAgICAgICAgIC8vIERldGFpbHMNCiAgICAgICAgICAgIGJvb2wgaGFzRGV0YWlsID0gc3RyaW5nLklzTnVsbE9yV2hpdGVTcGFjZShkZXRhaWxzKSA9PSBmYWxzZTsgICAgICAgICAgICANCiAgICAgICAgICAgIGlmIChoYXNEZXRhaWwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5EZXRhaWxzVGV4dC5UZXh0ID0gZGV0YWlsczsNCg0KICAgICAgICAgICAgICAgIHRoaXMuRGV0YWlsc0V4cGFuZGVyLlZpc2liaWxpdHkgPSBWaXNpYmlsaXR5LlZpc2libGU7DQogICAgICAgICAgICAgICAgdGhpcy5ncmlkU3BsaXR0ZXIwLlZpc2liaWxpdHkgPSBWaXNpYmlsaXR5LlZpc2libGU7DQogICAgICAgICAgICAgICAgdGhpcy5ncmlkU3BsaXR0ZXIxLlZpc2liaWxpdHkgPSBWaXNpYmlsaXR5LlZpc2libGU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5EZXRhaWxzRXhwYW5kZXIuVmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuQ29sbGFwc2VkOw0KICAgICAgICAgICAgICAgIHRoaXMuZ3JpZFNwbGl0dGVyMC5WaXNpYmlsaXR5ID0gVmlzaWJpbGl0eS5Db2xsYXBzZWQ7DQogICAgICAgICAgICAgICAgdGhpcy5ncmlkU3BsaXR0ZXIxLlZpc2liaWxpdHkgPSBWaXNpYmlsaXR5LkNvbGxhcHNlZDsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSBNZXNzYWdlQm94QnV0dG9uLlllc05vIHx8IGJ1dHRvbiA9PSBNZXNzYWdlQm94QnV0dG9uLlllc05vQ2FuY2VsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuS2V5RG93biArPSBuZXcgS2V5RXZlbnRIYW5kbGVyKE1lc3NhZ2VCb3hfS2V5RG93bik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHRoaXMuTG9hZGVkICs9IGZybV9Mb2FkZWQ7DQogICAgICAgICAgICB0aGlzLkNsb3NlZCArPSBmcm1fQ2xvc2VkOw0KICAgICAgICAgICAgdGhpcy5DbG9zaW5nICs9IGZybV9DbG9zaW5nOw0KICAgICAgICAgICAgdGhpcy5Nb3VzZURvd24gKz0gKHMsIGUpID0+IHsgaWYgKGUuQ2hhbmdlZEJ1dHRvbiA9PSBNb3VzZUJ1dHRvbi5MZWZ0KSB7IHRoaXMuRHJhZ01vdmUoKTsgfSB9Ow0KDQogICAgICAgICAgICB0aGlzLk9uQWN0aW9uID0gb25BY3Rpb247DQoNCiAgICAgICAgICAgIC8vIEF1dG9DbG9zZQ0KICAgICAgICAgICAgaWYgKGF1dG9DbG9zZVRpbWVTcGFuLkhhc1ZhbHVlID09IHRydWUpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgbVBsYW5UaWNrcyA9IGF1dG9DbG9zZVRpbWVTcGFuLlZhbHVlLlRpY2tzOw0KICAgICAgICAgICAgICAgIGxibEF1dG9DbG9zZS5UZXh0ID0gVG9TdHJpbmdBZHZTaW1wbGUoYXV0b0Nsb3NlVGltZVNwYW4uVmFsdWUpOw0KDQogICAgICAgICAgICAgICAgbURpc3BhdGNoZXJUaW1lciA9IG5ldyBTeXN0ZW0uV2luZG93cy5UaHJlYWRpbmcuRGlzcGF0Y2hlclRpbWVyKCk7DQogICAgICAgICAgICAgICAgbURpc3BhdGNoZXJUaW1lci5JbnRlcnZhbCA9IG1JbnRlcnZhbDsNCiAgICAgICAgICAgICAgICBtRGlzcGF0Y2hlclRpbWVyLlRpY2sgKz0gdGltZXJfVGljazsNCiAgICAgICAgICAgICAgICBtRGlzcGF0Y2hlclRpbWVyLlN0YXJ0KCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBwcml2YXRlIHZvaWQgZnJtX0Nsb3NlZChvYmplY3Qgc2VuZGVyLCBFdmVudEFyZ3MgZSkNCiAgICAgICAgew0KICAgICAgICAgICAgY2xvc2VEaXNwYXRjaGVyVGltZXIoKTsNCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICB2b2lkIE1lc3NhZ2VCb3hfS2V5RG93bihvYmplY3Qgc2VuZGVyLCBLZXlFdmVudEFyZ3MgZSkNCiAgICAgICAgew0KICAgICAgICAgICAgTW9kaWZpZXJLZXlzIG1vZGlmaWVycyA9IGUuS2V5Ym9hcmREZXZpY2UuTW9kaWZpZXJzOw0KDQogICAgICAgICAgICBpZiAoZS5TeXN0ZW1LZXkgPT0gS2V5LlkgJiYgKGludCltb2RpZmllcnMgPT0gKGludCkoTW9kaWZpZXJLZXlzLkFsdCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKHRoaXMuQnV0dG9uMCAhPSBudWxsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24wLkZvY3VzKCk7DQoNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5NZXNzYWdlQm94UmVzdWx0ID0gKE1lc3NhZ2VCb3hSZXN1bHQpdGhpcy5CdXR0b24wLlRhZzsNCg0KICAgICAgICAgICAgICAgICAgICB0aGlzLkNsb3NlKCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoZS5TeXN0ZW1LZXkgPT0gS2V5Lk4gJiYgKGludCltb2RpZmllcnMgPT0gKGludCkoTW9kaWZpZXJLZXlzLkFsdCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKHRoaXMuQnV0dG9uMSAhPSBudWxsKQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24xLkZvY3VzKCk7DQoNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5NZXNzYWdlQm94UmVzdWx0ID0gKE1lc3NhZ2VCb3hSZXN1bHQpdGhpcy5CdXR0b24xLlRhZzsNCg0KICAgICAgICAgICAgICAgICAgICB0aGlzLkNsb3NlKCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyDnlKjmiLfpgInmi6nnmoTnu5PmnpwNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIE1lc3NhZ2VCb3hSZXN1bHQgTWVzc2FnZUJveFJlc3VsdCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0NCg0KICAgICAgICAjcmVnaW9uIENyZWF0ZSBCdXR0b25zDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBtZXNzYWdlIGJveCdzIGJ1dHRvbiBhY2NvcmRpbmcgdG8gdGhlIHVzZXIncyBkZW1hbmQNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJidXR0b24iPlRoZSB1c2VyJ3MgYnV0dG9ucyBzZWxlY3Rpb248L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVCdXR0b25zKE1lc3NhZ2VCb3hCdXR0b24gYnV0dG9uLCBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHN3aXRjaCAoYnV0dG9uKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEJ1dHRvbi5PSzoNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24wID0gdGhpcy5DcmVhdGVPa0J1dHRvbihkZWZhdWx0UmVzdWx0KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZCh0aGlzLkJ1dHRvbjApOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEJ1dHRvbi5PS0NhbmNlbDoNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24wID0gdGhpcy5DcmVhdGVPa0J1dHRvbihkZWZhdWx0UmVzdWx0KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uMSA9IHRoaXMuQ3JlYXRlQ2FuY2VsQnV0dG9uKGRlZmF1bHRSZXN1bHQpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkJ1dHRvbnNQYW5lbC5DaGlsZHJlbi5BZGQodGhpcy5CdXR0b24wKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZCh0aGlzLkJ1dHRvbjEpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEJ1dHRvbi5ZZXNObzoNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24wID0gdGhpcy5DcmVhdGVZZXNCdXR0b24oZGVmYXVsdFJlc3VsdCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkJ1dHRvbjEgPSB0aGlzLkNyZWF0ZU5vQnV0dG9uKGRlZmF1bHRSZXN1bHQpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkJ1dHRvbnNQYW5lbC5DaGlsZHJlbi5BZGQodGhpcy5CdXR0b24wKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZCh0aGlzLkJ1dHRvbjEpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEJ1dHRvbi5ZZXNOb0NhbmNlbDoNCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24wID0gdGhpcy5DcmVhdGVZZXNCdXR0b24oZGVmYXVsdFJlc3VsdCk7DQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLkJ1dHRvbjEgPSB0aGlzLkNyZWF0ZU5vQnV0dG9uKGRlZmF1bHRSZXN1bHQpOw0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5CdXR0b24yID0gdGhpcy5DcmVhdGVDYW5jZWxCdXR0b24oZGVmYXVsdFJlc3VsdCk7DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZChCdXR0b24wKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZChCdXR0b24xKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuQnV0dG9uc1BhbmVsLkNoaWxkcmVuLkFkZChCdXR0b24yKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICBkZWZhdWx0Og0KICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXJndW1lbnRPdXRPZlJhbmdlRXhjZXB0aW9uKCJidXR0b24iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHN0YXRpYyBkb3VibGUgQnRuV2lkdGggPSBEb3VibGUuTmFOOw0KICAgICAgICBzdGF0aWMgZG91YmxlIEJ0bkhlaWdodCA9IERvdWJsZS5OYU47DQogICAgICAgIHN0YXRpYyBUaGlja25lc3MgTWVzc2FnZUJveEJ1dHRvbk1hcmdpbiA9IG5ldyBUaGlja25lc3MoMCwgMTAsIDUsIDUpOw0KDQogICAgICAgIC8vIHByaXZhdGUgQnV0dG9uIG9rQnV0dG9uOw0KICAgICAgICAvLyBwcml2YXRlIEJ1dHRvbiB5ZXNCdXR0b247DQogICAgICAgIC8vIHByaXZhdGUgQnV0dG9uIG5vQnV0dG9uOw0KDQogICAgICAgIHByaXZhdGUgQnV0dG9uIEJ1dHRvbjA7DQogICAgICAgIHByaXZhdGUgQnV0dG9uIEJ1dHRvbjE7DQogICAgICAgIHByaXZhdGUgQnV0dG9uIEJ1dHRvbjI7DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBvayBidXR0b24gb24gZGVtYW5kDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+PC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4NCiAgICAgICAgcHJpdmF0ZSBCdXR0b24gQ3JlYXRlT2tCdXR0b24oTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0KQ0KICAgICAgICB7DQogICAgICAgICAgICB2YXIgciA9IG5ldyBDbGllbnQuQ29tcG9uZW50cy5CdXR0b25CYXNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgTmFtZSA9ICJva0J1dHRvbiIsDQogICAgICAgICAgICAgICAgV2lkdGggPSBCdG5XaWR0aCwNCiAgICAgICAgICAgICAgICBIZWlnaHQgPSBCdG5IZWlnaHQsDQogICAgICAgICAgICAgICAgTWFyZ2luID0gTWVzc2FnZUJveEJ1dHRvbk1hcmdpbiwNCiAgICAgICAgICAgICAgICBUaXRsZSA9ICLnoa7lrpoiLCAvLyAiT0siLA0KICAgICAgICAgICAgICAgIElzRGVmYXVsdCA9IGRlZmF1bHRSZXN1bHQgPT0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICBUYWcgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgfTsNCg0KICAgICAgICAgICAgci5XaWR0aCArPSB0aGlzLkZvbnRTaXplOw0KICAgICAgICAgICAgci5IZWlnaHQgKz0gdGhpcy5Gb250U2l6ZTsNCiAgICAgICAgICAgIHIuQ2xpY2sgKz0gQnV0dG9uQ2xpY2s7DQoNCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBjYW5jZWwgYnV0dG9uIG9uIGRlbWFuZA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIHByaXZhdGUgQnV0dG9uIENyZWF0ZUNhbmNlbEJ1dHRvbihNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciByID0gbmV3IENsaWVudC5Db21wb25lbnRzLkJ1dHRvbkJhc2UNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBOYW1lID0gImNhbmNlbEJ1dHRvbiIsDQogICAgICAgICAgICAgICAgV2lkdGggPSBCdG5XaWR0aCwNCiAgICAgICAgICAgICAgICBIZWlnaHQgPSBCdG5IZWlnaHQsDQogICAgICAgICAgICAgICAgTWFyZ2luID0gTWVzc2FnZUJveEJ1dHRvbk1hcmdpbiwNCiAgICAgICAgICAgICAgICBUaXRsZSA9ICLlj5bmtogiLCAvLyJDYW5jZWwiLA0KICAgICAgICAgICAgICAgIElzRGVmYXVsdCA9IGRlZmF1bHRSZXN1bHQgPT0gTWVzc2FnZUJveFJlc3VsdC5DYW5jZWwsDQogICAgICAgICAgICAgICAgSXNDYW5jZWwgPSB0cnVlLA0KICAgICAgICAgICAgICAgIFRhZyA9IE1lc3NhZ2VCb3hSZXN1bHQuQ2FuY2VsLA0KICAgICAgICAgICAgfTsNCg0KICAgICAgICAgICAgci5XaWR0aCArPSB0aGlzLkZvbnRTaXplOw0KICAgICAgICAgICAgci5IZWlnaHQgKz0gdGhpcy5Gb250U2l6ZTsNCiAgICAgICAgICAgIHIuQ2xpY2sgKz0gQnV0dG9uQ2xpY2s7DQoNCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ3JlYXRlIHRoZSB5ZXMgYnV0dG9uIG9uIGRlbWFuZA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIHByaXZhdGUgQnV0dG9uIENyZWF0ZVllc0J1dHRvbihNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQpDQogICAgICAgIHsNCiAgICAgICAgICAgIC8vIFRPRE8g5pivKFkpIOWmguS9leWcqCBCdXR0b25CYXNlIOS4reaYvuekug0KICAgICAgICAgICAgLy92YXIgY29udGVudCA9IG5ldyBUZXh0QmxvY2soKTsNCiAgICAgICAgICAgIC8vY29udGVudC5JbmxpbmVzLkFkZCgi5pivKCIpOw0KICAgICAgICAgICAgLy9jb250ZW50LklubGluZXMuQWRkKG5ldyBSdW4oIlkiKSB7IFRleHREZWNvcmF0aW9ucyA9IFRleHREZWNvcmF0aW9ucy5VbmRlcmxpbmUgfSk7DQogICAgICAgICAgICAvL2NvbnRlbnQuSW5saW5lcy5BZGQoIikiKTsNCg0KICAgICAgICAgICAgdmFyIHIgPSBuZXcgQ2xpZW50LkNvbXBvbmVudHMuQnV0dG9uQmFzZQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIE5hbWUgPSAieWVzQnV0dG9uIiwNCiAgICAgICAgICAgICAgICBXaWR0aCA9IEJ0bldpZHRoLA0KICAgICAgICAgICAgICAgIEhlaWdodCA9IEJ0bkhlaWdodCwNCiAgICAgICAgICAgICAgICBNYXJnaW4gPSBNZXNzYWdlQm94QnV0dG9uTWFyZ2luLA0KICAgICAgICAgICAgICAgIFRpdGxlID0gIuaYryIsDQogICAgICAgICAgICAgICAgSXNEZWZhdWx0ID0gZGVmYXVsdFJlc3VsdCA9PSBNZXNzYWdlQm94UmVzdWx0LlllcywNCiAgICAgICAgICAgICAgICBUYWcgPSBNZXNzYWdlQm94UmVzdWx0LlllcywNCiAgICAgICAgICAgIH07DQoNCiAgICAgICAgICAgIHIuV2lkdGggKz0gdGhpcy5Gb250U2l6ZTsNCiAgICAgICAgICAgIHIuSGVpZ2h0ICs9IHRoaXMuRm9udFNpemU7DQogICAgICAgICAgICByLkNsaWNrICs9IEJ1dHRvbkNsaWNrOw0KDQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIENyZWF0ZSB0aGUgbm8gYnV0dG9uIG9uIGRlbWFuZA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIHByaXZhdGUgQnV0dG9uIENyZWF0ZU5vQnV0dG9uKE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCkNCiAgICAgICAgew0KICAgICAgICAgICAgLy8gVE9ETyDlkKYoTikg5aaC5L2V5ZyoIEJ1dHRvbkJhc2Ug5Lit5pi+56S6DQogICAgICAgICAgICAvL3ZhciBjb250ZW50ID0gbmV3IFRleHRCbG9jaygpOw0KICAgICAgICAgICAgLy9jb250ZW50LklubGluZXMuQWRkKCLlkKYoIik7DQogICAgICAgICAgICAvL2NvbnRlbnQuSW5saW5lcy5BZGQobmV3IFJ1bigiTiIpIHsgVGV4dERlY29yYXRpb25zID0gVGV4dERlY29yYXRpb25zLlVuZGVybGluZSB9KTsNCiAgICAgICAgICAgIC8vY29udGVudC5JbmxpbmVzLkFkZCgiKSIpOw0KDQogICAgICAgICAgICB2YXIgciA9IG5ldyBDbGllbnQuQ29tcG9uZW50cy5CdXR0b25CYXNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgTmFtZSA9ICJub0J1dHRvbiIsDQogICAgICAgICAgICAgICAgV2lkdGggPSBCdG5XaWR0aCwNCiAgICAgICAgICAgICAgICBIZWlnaHQgPSBCdG5IZWlnaHQsDQogICAgICAgICAgICAgICAgTWFyZ2luID0gTWVzc2FnZUJveEJ1dHRvbk1hcmdpbiwNCiAgICAgICAgICAgICAgICBUaXRsZSA9ICLlkKYiLA0KICAgICAgICAgICAgICAgIElzRGVmYXVsdCA9IGRlZmF1bHRSZXN1bHQgPT0gTWVzc2FnZUJveFJlc3VsdC5ObywNCiAgICAgICAgICAgICAgICBUYWcgPSBNZXNzYWdlQm94UmVzdWx0Lk5vLA0KICAgICAgICAgICAgfTsNCg0KICAgICAgICAgICAgci5XaWR0aCArPSB0aGlzLkZvbnRTaXplOw0KICAgICAgICAgICAgci5IZWlnaHQgKz0gdGhpcy5Gb250U2l6ZTsNCiAgICAgICAgICAgIHIuQ2xpY2sgKz0gQnV0dG9uQ2xpY2s7DQoNCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVGhlIGV2ZW50IHRoZSBidXR0b25zIHRyaWdnZXIuIA0KICAgICAgICAvLy8gRWFjaCBidXR0b24gaG9sZCBpdCdzIHJlc3VsdCBpbiB0aGUgdGFnLCBzbyBoZXJlIGl0IGp1c3Qgc2V0cyB0aGVtIGFuZCBjbG9zZSB0aGUgbWVzc2FnZSBib3guDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2VuZGVyIj48L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImUiPjwvcGFyYW0+DQogICAgICAgIHByaXZhdGUgdm9pZCBCdXR0b25DbGljayhvYmplY3Qgc2VuZGVyLCBSb3V0ZWRFdmVudEFyZ3MgZSkNCiAgICAgICAgew0KICAgICAgICAgICAgdmFyIGJ0biA9IHNlbmRlciBhcyBCdXR0b247DQogICAgICAgICAgICB2YXIgdmFsdWUgPSAoTWVzc2FnZUJveFJlc3VsdClidG4uVGFnOw0KDQogICAgICAgICAgICBpZg0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIC8vIOeCueWHu1vnoa7orqTmjInpkq5d5ZCODQogICAgICAgICAgICAgICAgKHZhbHVlID09IE1lc3NhZ2VCb3hSZXN1bHQuWWVzIHx8IHZhbHVlID09IE1lc3NhZ2VCb3hSZXN1bHQuT0spDQoNCiAgICAgICAgICAgICAgICAvLyDoi6XlkKvmnIkgRXh0cmFDb250ZW5077yM6ZyA6KaB6aqM6K+BIElEYXRhRXJyb3JJbmZvIOaOpeWPo+eahCBFcnJvciDlsZ7mgKcNCiAgICAgICAgICAgICAgICAvLyDlvZMgRXJyb3LlsZ7mgKcg6Z2e56m677yM5omN6IO957un57ut5ZCO57ut55qE6YC76L6RDQogICAgICAgICAgICAgICAgJiYgdGhpcy5FeHRyYUNvbnRlbnQgIT0gbnVsbA0KICAgICAgICAgICAgICAgICYmIHRoaXMuRXh0cmFDb250ZW50IGlzIENvbnRlbnRDb250cm9sIGNjDQogICAgICAgICAgICAgICAgJiYgY2MuRGF0YUNvbnRleHQgaXMgSURhdGFFcnJvckluZm8gZGF0YUNvbnRleHQNCiAgICAgICAgICAgICAgICAmJiBzdHJpbmcuSXNOdWxsT3JXaGl0ZVNwYWNlKGRhdGFDb250ZXh0LkVycm9yKSA9PSBmYWxzZQ0KICAgICAgICAgICAgKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIFN5c3RlbS5EaWFnbm9zdGljcy5EZWJ1Zy5Xcml0ZUxpbmUoIuacqumAmui/hyBJRGF0YUVycm9ySW5mbyDpqozor4EiKTsNCiAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHRoaXMuTWVzc2FnZUJveFJlc3VsdCA9IHZhbHVlOw0KDQogICAgICAgICAgICBpZiAoT25GdW5jICE9IG51bGwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgYm9vbCByID0gT25GdW5jLkludm9rZSh0aGlzLCB2YWx1ZSk7DQogICAgICAgICAgICAgICAgaWYgKHIgPT0gZmFsc2UpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoT25BY3Rpb24gIT0gbnVsbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICBPbkFjdGlvbi5JbnZva2UodmFsdWUpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB0aGlzLkNsb3NlKCk7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgcHJpdmF0ZSB2b2lkIEFwcGx5T3B0aW9ucyhNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoKG9wdGlvbnMgJiBNZXNzYWdlQm94T3B0aW9ucy5SaWdodEFsaWduKSA9PSBNZXNzYWdlQm94T3B0aW9ucy5SaWdodEFsaWduKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHRoaXMuTWVzc2FnZVRleHQuVGV4dEFsaWdubWVudCA9IFRleHRBbGlnbm1lbnQuUmlnaHQ7DQogICAgICAgICAgICAgICAgdGhpcy5EZXRhaWxzVGV4dC5UZXh0QWxpZ25tZW50ID0gVGV4dEFsaWdubWVudC5SaWdodDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmICgob3B0aW9ucyAmIE1lc3NhZ2VCb3hPcHRpb25zLlJ0bFJlYWRpbmcpID09IE1lc3NhZ2VCb3hPcHRpb25zLlJ0bFJlYWRpbmcpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhpcy5GbG93RGlyZWN0aW9uID0gRmxvd0RpcmVjdGlvbi5SaWdodFRvTGVmdDsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICNyZWdpb24g5bem6L655Zu+5qCH55qE5Yib5bu6DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gQ3JlYXRlIHRoZSBpbWFnZSBmcm9tIHRoZSBzeXN0ZW0ncyBpY29ucw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPjwvcGFyYW0+DQogICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVJbWFnZShNZXNzYWdlQm94SW1hZ2UgaWNvbikNCiAgICAgICAgew0KICAgICAgICAgICAgc3dpdGNoIChpY29uKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEltYWdlLk5vbmU6DQogICAgICAgICAgICAgICAgICAgIHRoaXMuSW1hZ2VQbGFjZWhvbGRlci5WaXNpYmlsaXR5ID0gVmlzaWJpbGl0eS5Db2xsYXBzZWQ7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEltYWdlLkluZm9ybWF0aW9uOg0KICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gU3lzdGVtSWNvbnMuSW5mb3JtYXRpb24uVG9JbWFnZVNvdXJjZSgpOw0KICAgICAgICAgICAgICAgICAgICB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gVG9JbWFnZVNvdXJjZShTeXN0ZW1JY29ucy5JbmZvcm1hdGlvbik7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEltYWdlLlF1ZXN0aW9uOg0KICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gU3lzdGVtSWNvbnMuUXVlc3Rpb24uVG9JbWFnZVNvdXJjZSgpOw0KICAgICAgICAgICAgICAgICAgICB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gVG9JbWFnZVNvdXJjZShTeXN0ZW1JY29ucy5RdWVzdGlvbik7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEltYWdlLldhcm5pbmc6DQogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuSW1hZ2VQbGFjZWhvbGRlci5Tb3VyY2UgPSBTeXN0ZW1JY29ucy5XYXJuaW5nLlRvSW1hZ2VTb3VyY2UoKTsNCiAgICAgICAgICAgICAgICAgICAgdGhpcy5JbWFnZVBsYWNlaG9sZGVyLlNvdXJjZSA9IFRvSW1hZ2VTb3VyY2UoU3lzdGVtSWNvbnMuV2FybmluZyk7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGNhc2UgTWVzc2FnZUJveEltYWdlLkVycm9yOg0KICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gU3lzdGVtSWNvbnMuRXJyb3IuVG9JbWFnZVNvdXJjZSgpOw0KICAgICAgICAgICAgICAgICAgICB0aGlzLkltYWdlUGxhY2Vob2xkZXIuU291cmNlID0gVG9JbWFnZVNvdXJjZShTeXN0ZW1JY29ucy5FcnJvcik7DQogICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6DQogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBcmd1bWVudE91dE9mUmFuZ2VFeGNlcHRpb24oImljb24iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIFtEbGxJbXBvcnQoImdkaTMyLmRsbCIsIFNldExhc3RFcnJvciA9IHRydWUpXQ0KICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gYm9vbCBEZWxldGVPYmplY3QoSW50UHRyIGhPYmplY3QpOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIEljb24gMiBJbWFnZVNvdXJjZQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPmljb248L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+SW1hZ2VTb3VyY2U8L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgSW1hZ2VTb3VyY2UgVG9JbWFnZVNvdXJjZShJY29uIGljb24pDQogICAgICAgIHsNCiAgICAgICAgICAgIEJpdG1hcCBiaXRtYXAgPSBpY29uLlRvQml0bWFwKCk7DQogICAgICAgICAgICBJbnRQdHIgaGJpdG1hcCA9IGJpdG1hcC5HZXRIYml0bWFwKCk7DQogICAgICAgICAgICBJbWFnZVNvdXJjZSBpbWFnZVNvdXJjZSA9IFN5c3RlbS5XaW5kb3dzLkludGVyb3AuSW1hZ2luZy5DcmVhdGVCaXRtYXBTb3VyY2VGcm9tSEJpdG1hcChoYml0bWFwLCBJbnRQdHIuWmVybywgSW50MzJSZWN0LkVtcHR5LCBCaXRtYXBTaXplT3B0aW9ucy5Gcm9tRW1wdHlPcHRpb25zKCkpOw0KICAgICAgICAgICAgaWYgKCFEZWxldGVPYmplY3QoaGJpdG1hcCkpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFdpbjMyRXhjZXB0aW9uKCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gaW1hZ2VTb3VyY2UuR2V0QXNGcm96ZW4oKSBhcyBJbWFnZVNvdXJjZTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBTaG93IHRoZSBzdGFydHVwIGFuaW1hdGlvbg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNlbmRlciI+PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlIj48L3BhcmFtPg0KICAgICAgICB2b2lkIGZybV9Mb2FkZWQob2JqZWN0IHNlbmRlciwgUm91dGVkRXZlbnRBcmdzIGUpDQogICAgICAgIHsNCiAgICAgICAgICAgICNyZWdpb24gIEFkZCBCeSBob3dlDQoNCiAgICAgICAgICAgIC8vIERldGFpbHNFeHBhbmRlci5Jc0V4cGFuZGVkID0gZmFsc2U7DQoNCiAgICAgICAgICAgIC8vIHZhciByZWN0ID0gUHJpbWFyeVNjcmVlbldvcmtpbmdBcmVhKCk7DQogICAgICAgICAgICB2YXIgc2NyZWVuID0gV1BGQ29udHJvbHMuU2NyZWVuVXRpbHMuU2NyZWVuLkZyb21Qb2ludChXUEZDb250cm9scy5TY3JlZW5VdGlscy5Nb3VzZVV0aWxzLk1vdXNlUG9zaXRpb24pOw0KICAgICAgICAgICAgdmFyIHJlY3QgPSBzY3JlZW4uV29ya2luZ0FyZWE7DQoNCiAgICAgICAgICAgIGRvdWJsZSBtYXhXaWR0aCA9IChkb3VibGUpcmVjdC5XaWR0aCAqIDAuNmQ7DQogICAgICAgICAgICB0aGlzLk1heFdpZHRoID0gbWF4V2lkdGggKyAxMDsNCiAgICAgICAgICAgIGdyaWRNYWluLk1heFdpZHRoID0gbWF4V2lkdGg7DQogICAgICAgICAgICBncmlkU3BsaXR0ZXIwLk1heFdpZHRoID0gbWF4V2lkdGg7DQogICAgICAgICAgICBncmlkU3BsaXR0ZXIxLk1heFdpZHRoID0gbWF4V2lkdGg7DQogICAgICAgICAgICBncmlkRGV0YWlsLk1heFdpZHRoID0gbWF4V2lkdGg7DQoNCiAgICAgICAgICAgIGRvdWJsZSBtYXJnaW5IZWlnaHQgPSA1Ow0KICAgICAgICAgICAgZG91YmxlIGdyaWRTcGxpdHRlckhlaWdodCA9IDM7DQoNCiAgICAgICAgICAgIHRoaXNXaW5kb3cuTWF4SGVpZ2h0ID0gcmVjdC5IZWlnaHQgLSAobWFyZ2luSGVpZ2h0ICogMik7DQoNCiAgICAgICAgICAgIGRvdWJsZSBncmlkTWFpbk1pbmlIZWlnaHQgPSA2MDsNCiAgICAgICAgICAgIGRvdWJsZSB0b3RhbEhlaWdodCA9IHJlY3QuSGVpZ2h0IC0gKG1hcmdpbkhlaWdodCAqIDIpIC0gZ3JpZFNwbGl0dGVySGVpZ2h0Ow0KICAgICAgICAgICAgZ3JpZE1haW4uTWluSGVpZ2h0ID0gZ3JpZE1haW5NaW5pSGVpZ2h0Ow0KICAgICAgICAgICAgZ3JpZE1haW4uTWF4SGVpZ2h0ID0gdG90YWxIZWlnaHQ7DQoNCg0KICAgICAgICAgICAgZ3JpZERldGFpbC5NaW5IZWlnaHQgPSA0MDsNCiAgICAgICAgICAgIGdyaWREZXRhaWwuTWF4SGVpZ2h0ID0gdG90YWxIZWlnaHQgLSBncmlkU3BsaXR0ZXJIZWlnaHQgLSBncmlkTWFpbk1pbmlIZWlnaHQ7DQoNCg0KICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHRoaXMuRGV0YWlsc1RleHQuVGV4dCkgPT0gZmFsc2UpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKGdyaWREZXRhaWwuTWluV2lkdGggPCBCdXR0b25zUGFuZWwuQWN0dWFsV2lkdGgpDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBkb3VibGUgbWluV2lkdGggPSBCdXR0b25zUGFuZWwuQWN0dWFsV2lkdGg7DQoNCiAgICAgICAgICAgICAgICAgICAgbWluV2lkdGggKz0gemhhbndlaWZ1LkFjdHVhbFdpZHRoOyAvLyDorqHnrpflt6bovrnor6bmg4XnmoTlrp7pmYXlrr3luqYNCg0KICAgICAgICAgICAgICAgICAgICB0aGlzLk1pbldpZHRoID0gbWluV2lkdGggKyAyMDsNCiAgICAgICAgICAgICAgICAgICAgZ3JpZE1haW4uTWluV2lkdGggPSBtaW5XaWR0aDsNCiAgICAgICAgICAgICAgICAgICAgZ3JpZERldGFpbC5NaW5XaWR0aCA9IG1pbldpZHRoOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICAgICAjcmVnaW9uIExvYWRlZA0KDQogICAgICAgICAgICAvLyBUaGlzIGlzIHNldCBoZXJlIHRvIGhlaWdodCBhZnRlciB0aGUgd2lkdGggaGFzIGJlZW4gc2V0IA0KICAgICAgICAgICAgLy8gc28gdGhlIGRldGFpbHMgZXhwYW5kZXIgd29uJ3Qgc3RyZXRjaCB0aGUgbWVzc2FnZSBib3ggd2hlbiBpdCdzIG9wZW5lZA0KICAgICAgICAgICAgdGhpcy5TaXplVG9Db250ZW50ID0gU2l6ZVRvQ29udGVudC5IZWlnaHQ7DQogICAgICAgICAgICAvL3ZhciBhbmltYXRpb24gPSBUcnlGaW5kUmVzb3VyY2UoIkxvYWRBbmltYXRpb24iKSBhcyBTdG9yeWJvYXJkOw0KICAgICAgICAgICAgLy9hbmltYXRpb24uQmVnaW4odGhpcyk7DQoNCiAgICAgICAgICAgIC8vIOWFs+azqOaMiemSrueEpueCuQ0KICAgICAgICAgICAgTG9hZGVkX0J1dHRvbkZvY3VzKEJ1dHRvbjApOw0KICAgICAgICAgICAgTG9hZGVkX0J1dHRvbkZvY3VzKEJ1dHRvbjEpOw0KICAgICAgICAgICAgTG9hZGVkX0J1dHRvbkZvY3VzKEJ1dHRvbjIpOw0KDQogICAgICAgICAgICAjZW5kcmVnaW9uDQogICAgICAgIH0NCg0KICAgICAgICB2b2lkIExvYWRlZF9CdXR0b25Gb2N1cyhCdXR0b24gYnRuKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoYnRuICE9IG51bGwgJiYgYnRuLklzSW5pdGlhbGl6ZWQgPT0gdHJ1ZSAmJiBidG4uSXNEZWZhdWx0ID09IHRydWUpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgYnRuLkZvY3VzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBTaG93IHRoZSBjbG9zaW5nIGFuaW1hdGlvbg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNlbmRlciI+PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlIj48L3BhcmFtPg0KICAgICAgICBwcml2YXRlIHZvaWQgZnJtX0Nsb3Npbmcob2JqZWN0IHNlbmRlciwgQ2FuY2VsRXZlbnRBcmdzIGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmICghdGhpcy5tQW5pbWF0aW9uUmFuKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIFRoZSBhbmltYXRpb24gd29uJ3QgcnVuIGlmIHRoZSB3aW5kb3cgaXMgYWxsb3dlZCB0byBjbG9zZSwgDQogICAgICAgICAgICAgICAgLy8gc28gaGVyZSB0aGUgYW5pbWF0aW9uIHN0YXJ0cywgYW5kIHRoZSB3aW5kb3cncyBjbG9zaW5nIGlzIGNhbmNlbGVkDQogICAgICAgICAgICAgICAgZS5DYW5jZWwgPSB0cnVlOw0KDQogICAgICAgICAgICAgICAgdmFyIGFuaW1hdGlvbiA9IFRyeUZpbmRSZXNvdXJjZSgiVW5sb2FkQW5pbWF0aW9uIikgYXMgU3Rvcnlib2FyZDsNCg0KICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5Db21wbGV0ZWQgKz0gKHMsIGEpID0+DQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB0aGlzLm1BbmltYXRpb25SYW4gPSB0cnVlOw0KICAgICAgICAgICAgICAgICAgICB0aGlzLkNsb3NlKCk7DQogICAgICAgICAgICAgICAgfTsNCg0KICAgICAgICAgICAgICAgIGFuaW1hdGlvbi5CZWdpbih0aGlzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICNyZWdpb24gU2hvdyBJbmZvcm1hdGlvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93IC0gSW5mb3JtYXRpb248L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gT0sgKC8gQ2FuY2VsICkgLS0g6buY6K6k5LiN5pi+56S6IENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICBwdWJsaWMgc3RhdGljIFdQRkNvbnRyb2xzLk1lc3NhZ2VCb3ggU2hvd0luZm9ybWF0aW9uKHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLCBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dJbmZvcm1hdGlvbg0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBudWxsLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBzaG93Q2FuY2VsOiBzaG93Q2FuY2VsLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBvbkFjdGlvbjogb25BY3Rpb24sDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3cgLSBJbmZvcm1hdGlvbjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICBwdWJsaWMgc3RhdGljIFdQRkNvbnRyb2xzLk1lc3NhZ2VCb3ggU2hvd0luZm9ybWF0aW9uKFdpbmRvdyBvd25lciwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3Rpb248TWVzc2FnZUJveFJlc3VsdD4gb25BY3Rpb24gPSBudWxsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93DQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG93bmVyLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBidXR0b246IHNob3dDYW5jZWwgPyBNZXNzYWdlQm94QnV0dG9uLk9LQ2FuY2VsIDogTWVzc2FnZUJveEJ1dHRvbi5PSywNCiAgICAgICAgICAgICAgICBpY29uOiBNZXNzYWdlQm94SW1hZ2UuSW5mb3JtYXRpb24sDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBTaG93RGlhbG9nIEluZm9ybWF0aW9uDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBJbmZvcm1hdGlvbjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hvd0NhbmNlbCI+RGlzcGxheSB0aGUgY2FuY2VsPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogT0s8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9wdGlvbnMiPk1pc2Mgb3B0aW9uczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICBwdWJsaWMgc3RhdGljIE1lc3NhZ2VCb3hSZXN1bHQgU2hvd0luZm9ybWF0aW9uRGlhbG9nKHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLCBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93SW5mb3JtYXRpb25EaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogbnVsbCwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgc2hvd0NhbmNlbDogc2hvd0NhbmNlbCwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBJbmZvcm1hdGlvbjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dJbmZvcm1hdGlvbkRpYWxvZyhXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2hvd0NhbmNlbCA9IGZhbHNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dEaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGJ1dHRvbjogc2hvd0NhbmNlbCA/IE1lc3NhZ2VCb3hCdXR0b24uT0tDYW5jZWwgOiBNZXNzYWdlQm94QnV0dG9uLk9LLA0KICAgICAgICAgICAgICAgIGljb246IE1lc3NhZ2VCb3hJbWFnZS5JbmZvcm1hdGlvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gU2hvdyBDb25maXJtDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3cgLSBDb25maXJtPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIE9LIC8gQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4gICAgICAgDQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dDb25maXJtKEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd0NvbmZpcm0NCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogbnVsbCwNCiAgICAgICAgICAgICAgICBvbkFjdGlvbjogb25BY3Rpb24sDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvdyAtIENvbmZpcm08L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gT0sgLyBDYW5jZWw8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3duZXIiPlRoZSBtZXNzYWdlIGJveCdzIHBhcmVudCB3aW5kb3c8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4gICAgICAgDQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dDb25maXJtKFdpbmRvdyBvd25lciwgQWN0aW9uPE1lc3NhZ2VCb3hSZXN1bHQ+IG9uQWN0aW9uLCBzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93DQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG93bmVyLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBNZXNzYWdlQm94QnV0dG9uLk9LQ2FuY2VsLA0KICAgICAgICAgICAgICAgIGljb246IE1lc3NhZ2VCb3hJbWFnZS5RdWVzdGlvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gU2hvd0RpYWxvZyBDb25maXJtDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBDb25maXJtPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIE9LIC8gQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dDb25maXJtRGlhbG9nKHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dDb25maXJtRGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG51bGwsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvd0RpYWxvZyAtIENvbmZpcm08L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gT0sgLyBDYW5jZWw8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3duZXIiPlRoZSBtZXNzYWdlIGJveCdzIHBhcmVudCB3aW5kb3c8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dDb25maXJtRGlhbG9nKFdpbmRvdyBvd25lciwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd0RpYWxvZw0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBNZXNzYWdlQm94QnV0dG9uLk9LQ2FuY2VsLA0KICAgICAgICAgICAgICAgIGljb246IE1lc3NhZ2VCb3hJbWFnZS5RdWVzdGlvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gU2hvdyBRdWVzdGlvbg0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93IC0gUXVlc3Rpb248L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gWWVzIC8gTm8gKCAvIENhbmNlbCApIC0tIOm7mOiupOS4jeaYvuekuiBDYW5jZWw8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib25BY3Rpb24iPuWbnuiwg+WHveaVsCwg5omn6KGMIFNob3cg5pa55rOV55So5oi354K55Ye75oyJ6ZKu5pe25Lya5omn6KGM5Zue6LCD5Ye95pWwPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IFllczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgV1BGQ29udHJvbHMuTWVzc2FnZUJveCBTaG93UXVlc3Rpb24oQWN0aW9uPE1lc3NhZ2VCb3hSZXN1bHQ+IG9uQWN0aW9uLCBzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0LlllcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd1F1ZXN0aW9uDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG51bGwsDQogICAgICAgICAgICAgICAgb25BY3Rpb246IG9uQWN0aW9uLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBzaG93Q2FuY2VsOiBzaG93Q2FuY2VsLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvdyAtIFF1ZXN0aW9uPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIFllcyAvIE5vICggLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvbkFjdGlvbiI+5Zue6LCD5Ye95pWwLCDmiafooYwgU2hvdyDmlrnms5XnlKjmiLfngrnlh7vmjInpkq7ml7bkvJrmiafooYzlm57osIPlh73mlbA8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hvd0NhbmNlbCI+RGlzcGxheSB0aGUgY2FuY2VsPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogWWVzPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dRdWVzdGlvbihXaW5kb3cgb3duZXIsIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5ZZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgb25BY3Rpb246IG9uQWN0aW9uLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBidXR0b246IHNob3dDYW5jZWwgPyBNZXNzYWdlQm94QnV0dG9uLlllc05vQ2FuY2VsIDogTWVzc2FnZUJveEJ1dHRvbi5ZZXNObywNCiAgICAgICAgICAgICAgICBpY29uOiBNZXNzYWdlQm94SW1hZ2UuUXVlc3Rpb24sDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFNob3dEaWFsb2cgUXVlc3Rpb24NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvd0RpYWxvZyAtIFF1ZXN0aW9uPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIFllcyAvIE5vICggLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hvd0NhbmNlbCI+RGlzcGxheSB0aGUgY2FuY2VsPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogWWVzPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dRdWVzdGlvbkRpYWxvZyhzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0LlllcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd1F1ZXN0aW9uRGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG51bGwsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIHNob3dDYW5jZWw6IHNob3dDYW5jZWwsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93RGlhbG9nIC0gUXVlc3Rpb248L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gWWVzIC8gTm8gKCAvIENhbmNlbCApIC0tIOm7mOiupOS4jeaYvuekuiBDYW5jZWw8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3duZXIiPlRoZSBtZXNzYWdlIGJveCdzIHBhcmVudCB3aW5kb3c8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hvd0NhbmNlbCI+RGlzcGxheSB0aGUgY2FuY2VsPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogWWVzPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dRdWVzdGlvbkRpYWxvZyhXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2hvd0NhbmNlbCA9IGZhbHNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuWWVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93RGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG93bmVyLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBidXR0b246IHNob3dDYW5jZWwgPyBNZXNzYWdlQm94QnV0dG9uLlllc05vQ2FuY2VsIDogTWVzc2FnZUJveEJ1dHRvbi5ZZXNObywNCiAgICAgICAgICAgICAgICBpY29uOiBNZXNzYWdlQm94SW1hZ2UuUXVlc3Rpb24sDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFNob3cgV2FybmluZw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93IC0gV2FybmluZzwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwpIC0tIOm7mOiupOmakOiXjzwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICBwdWJsaWMgc3RhdGljIFdQRkNvbnRyb2xzLk1lc3NhZ2VCb3ggU2hvd1dhcm5pbmcoc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd1dhcm5pbmcNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogbnVsbCwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgc2hvd0NhbmNlbDogc2hvd0NhbmNlbCwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgb25BY3Rpb246IG9uQWN0aW9uLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93IC0gV2FybmluZzwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwpIC0tIOm7mOiupOmakOiXjzwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaG93Q2FuY2VsIj5EaXNwbGF5IHRoZSBjYW5jZWw8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBPSzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvbkFjdGlvbiI+5Zue6LCD5Ye95pWwLCDmiafooYwgU2hvdyDmlrnms5XnlKjmiLfngrnlh7vmjInpkq7ml7bkvJrmiafooYzlm57osIPlh73mlbA8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dXYXJuaW5nKFdpbmRvdyBvd25lciwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvdw0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBzaG93Q2FuY2VsID8gTWVzc2FnZUJveEJ1dHRvbi5PS0NhbmNlbCA6IE1lc3NhZ2VCb3hCdXR0b24uT0ssDQogICAgICAgICAgICAgICAgaWNvbjogTWVzc2FnZUJveEltYWdlLldhcm5pbmcsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBTaG93RGlhbG9nIFdhcm5pbmcNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvd0RpYWxvZyAtIFdhcm5pbmc8L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gT0sgKC8gQ2FuY2VsKSAtLSDpu5jorqTpmpDol488L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaG93Q2FuY2VsIj5EaXNwbGF5IHRoZSBjYW5jZWw8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBPSzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZUJveFJlc3VsdCBTaG93V2FybmluZ0RpYWxvZyhzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2hvd0NhbmNlbCA9IGZhbHNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dXYXJuaW5nRGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG51bGwsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIHNob3dDYW5jZWw6IHNob3dDYW5jZWwsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93RGlhbG9nIC0gV2FybmluZzwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAoLyBDYW5jZWwpIC0tIOm7mOiupOmakOiXjzwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaG93Q2FuY2VsIj5EaXNwbGF5IHRoZSBjYW5jZWw8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBPSzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZUJveFJlc3VsdCBTaG93V2FybmluZ0RpYWxvZyhXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICByZXR1cm4gU2hvd0RpYWxvZw0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBzaG93Q2FuY2VsID8gTWVzc2FnZUJveEJ1dHRvbi5PS0NhbmNlbCA6IE1lc3NhZ2VCb3hCdXR0b24uT0ssDQogICAgICAgICAgICAgICAgaWNvbjogTWVzc2FnZUJveEltYWdlLldhcm5pbmcsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFNob3cgRXJyb3INCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvdyAtIEVycm9yPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIE9rICggLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImV4Y2VwdGlvbiI+5Lyg5YWlIEV4Y2VwdGlvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hvd0NhbmNlbCI+RGlzcGxheSB0aGUgY2FuY2VsPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogT0s8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9wdGlvbnMiPk1pc2Mgb3B0aW9uczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib25BY3Rpb24iPuWbnuiwg+WHveaVsCwg5omn6KGMIFNob3cg5pa55rOV55So5oi354K55Ye75oyJ6ZKu5pe25Lya5omn6KGM5Zue6LCD5Ye95pWwPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgV1BGQ29udHJvbHMuTWVzc2FnZUJveCBTaG93RXJyb3IoRXhjZXB0aW9uIGV4Y2VwdGlvbiwgc3RyaW5nIG1lc3NhZ2UgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dFcnJvcg0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBudWxsLA0KICAgICAgICAgICAgICAgIGV4Y2VwdGlvbjogZXhjZXB0aW9uLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgc2hvd0NhbmNlbDogc2hvd0NhbmNlbCwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgb25BY3Rpb246IG9uQWN0aW9uLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPk1zZ0JveC5TaG93IC0gRXJyb3I8L3BhcmE+DQogICAgICAgIC8vLyA8cGFyYT7ov5Tlm54gT2sgKCAvIENhbmNlbCApIC0tIOm7mOiupOS4jeaYvuekuiBDYW5jZWw8L3BhcmE+DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaG93Q2FuY2VsIj5EaXNwbGF5IHRoZSBjYW5jZWw8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBPSzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvbkFjdGlvbiI+5Zue6LCD5Ye95pWwLCDmiafooYwgU2hvdyDmlrnms5XnlKjmiLfngrnlh7vmjInpkq7ml7bkvJrmiafooYzlm57osIPlh73mlbA8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dFcnJvcihzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGlvbjxNZXNzYWdlQm94UmVzdWx0PiBvbkFjdGlvbiA9IG51bGwsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dFcnJvcg0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBudWxsLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBzaG93Q2FuY2VsOiBzaG93Q2FuY2VsLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBvbkFjdGlvbjogb25BY3Rpb24sDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3cgLSBFcnJvcjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPayAoIC8gQ2FuY2VsICkgLS0g6buY6K6k5LiN5pi+56S6IENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZXhjZXB0aW9uIj7kvKDlhaUgRXhjZXB0aW9uPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzaG93Q2FuY2VsIj5EaXNwbGF5IHRoZSBjYW5jZWw8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPum7mOiupOe7k+aenOS4uiBPSzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvbkFjdGlvbiI+5Zue6LCD5Ye95pWwLCDmiafooYwgU2hvdyDmlrnms5XnlKjmiLfngrnlh7vmjInpkq7ml7bkvJrmiafooYzlm57osIPlh73mlbA8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3dFcnJvcihXaW5kb3cgb3duZXIsIEV4Y2VwdGlvbiBleGNlcHRpb24sIHN0cmluZyBtZXNzYWdlID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3Rpb248TWVzc2FnZUJveFJlc3VsdD4gb25BY3Rpb24gPSBudWxsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHN0cmluZyBkZXRhaWxzID0gc3RyaW5nLkVtcHR5Ow0KDQogICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9IG51bGwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgZGV0YWlscyA9IEV4Y2VwdGlvbkdldEluZm8oZXhjZXB0aW9uKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgcmV0dXJuIFNob3dFcnJvcg0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBzdHJpbmcuSXNOdWxsT3JFbXB0eShtZXNzYWdlKSA/IGV4Y2VwdGlvbi5NZXNzYWdlIDogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIHNob3dDYW5jZWw6IHNob3dDYW5jZWwsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvdyAtIEVycm9yPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIE9rICggLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9uQWN0aW9uIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICBwdWJsaWMgc3RhdGljIFdQRkNvbnRyb2xzLk1lc3NhZ2VCb3ggU2hvd0Vycm9yKFdpbmRvdyBvd25lciwgc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3Rpb248TWVzc2FnZUJveFJlc3VsdD4gb25BY3Rpb24gPSBudWxsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93DQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG93bmVyLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBidXR0b246IHNob3dDYW5jZWwgPyBNZXNzYWdlQm94QnV0dG9uLk9LQ2FuY2VsIDogTWVzc2FnZUJveEJ1dHRvbi5PSywNCiAgICAgICAgICAgICAgICBpY29uOiBNZXNzYWdlQm94SW1hZ2UuRXJyb3IsDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBTaG93RGlhbG9nIEVycm9yDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBFcnJvcjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPayAoIC8gQ2FuY2VsICkgLS0g6buY6K6k5LiN5pi+56S6IENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJleGNlcHRpb24iPuS8oOWFpSBFeGNlcHRpb248L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dFcnJvckRpYWxvZyhFeGNlcHRpb24gZXhjZXB0aW9uLCBzdHJpbmcgbWVzc2FnZSA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2hvd0NhbmNlbCA9IGZhbHNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dFcnJvckRpYWxvZw0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBudWxsLA0KICAgICAgICAgICAgICAgIGV4Y2VwdGlvbjogZXhjZXB0aW9uLA0KICAgICAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgc2hvd0NhbmNlbDogc2hvd0NhbmNlbCwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBFcnJvcjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPayAoIC8gQ2FuY2VsICkgLS0g6buY6K6k5LiN5pi+56S6IENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dFcnJvckRpYWxvZyhzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIHNob3dDYW5jZWwgPSBmYWxzZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93RXJyb3JEaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogbnVsbCwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgc2hvd0NhbmNlbDogc2hvd0NhbmNlbCwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmE+TXNnQm94LlNob3dEaWFsb2cgLSBFcnJvcjwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPayAoIC8gQ2FuY2VsICkgLS0g6buY6K6k5LiN5pi+56S6IENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZXhjZXB0aW9uIj7kvKDlhaUgRXhjZXB0aW9uPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4gICAgICAgIA0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dFcnJvckRpYWxvZyhXaW5kb3cgb3duZXIsIEV4Y2VwdGlvbiBleGNlcHRpb24sIHN0cmluZyBtZXNzYWdlID0gIiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBzaG93Q2FuY2VsID0gZmFsc2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICBzdHJpbmcgZGV0YWlscyA9IHN0cmluZy5FbXB0eTsNCg0KICAgICAgICAgICAgaWYgKGV4Y2VwdGlvbiAhPSBudWxsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGRldGFpbHMgPSBFeGNlcHRpb25HZXRJbmZvKGV4Y2VwdGlvbik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHJldHVybiBTaG93RXJyb3JEaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogc3RyaW5nLklzTnVsbE9yRW1wdHkobWVzc2FnZSkgPyBleGNlcHRpb24uTWVzc2FnZSA6IG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgZGV0YWlsczogZGV0YWlscywNCiAgICAgICAgICAgICAgICBzaG93Q2FuY2VsOiBzaG93Q2FuY2VsLA0KICAgICAgICAgICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9ucywNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYT5Nc2dCb3guU2hvd0RpYWxvZyAtIEVycm9yPC9wYXJhPg0KICAgICAgICAvLy8gPHBhcmE+6L+U5ZueIE9rICggLyBDYW5jZWwgKSAtLSDpu5jorqTkuI3mmL7npLogQ2FuY2VsPC9wYXJhPg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InNob3dDYW5jZWwiPkRpc3BsYXkgdGhlIGNhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+6buY6K6k57uT5p6c5Li6IE9LPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dFcnJvckRpYWxvZyhXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2hvd0NhbmNlbCA9IGZhbHNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dEaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGJ1dHRvbjogc2hvd0NhbmNlbCA/IE1lc3NhZ2VCb3hCdXR0b24uT0tDYW5jZWwgOiBNZXNzYWdlQm94QnV0dG9uLk9LLA0KICAgICAgICAgICAgICAgIGljb246IE1lc3NhZ2VCb3hJbWFnZS5FcnJvciwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gU2hvdw0KDQogICAgICAgIC8vLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8vLyBTaG93IHRoZSBtZXNzYWdlIGJveCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycw0KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJidXR0b24iPlRoZSBidXR0b25zIHRvIGJlIGRpc3BsYXllZDwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJpY29uIj5UaGUgbWVzc2FnZSdzIHNldmVyaXR5PC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIC8vcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3coc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBkZXRhaWxzID0gIiIsDQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveEJ1dHRvbiBidXR0b24gPSBNZXNzYWdlQm94QnV0dG9uLk9LLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hJbWFnZSBpY29uID0gTWVzc2FnZUJveEltYWdlLk5vbmUsDQogICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5Ob25lLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIC8vew0KICAgICAgICAvLyAgICByZXR1cm4gU2hvdw0KICAgICAgICAvLyAgICAoDQogICAgICAgIC8vICAgICAgICBvd25lcjogbnVsbCwNCiAgICAgICAgLy8gICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsDQogICAgICAgIC8vICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAvLyAgICAgICAgYnV0dG9uOiBidXR0b24sDQogICAgICAgIC8vICAgICAgICBpY29uOiBpY29uLA0KICAgICAgICAvLyAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgLy8gICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgIC8vICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgLy8gICAgKTsNCiAgICAgICAgLy99DQoNCiAgICAgICAgLy8vLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLy8vIFNob3cgdGhlIG1lc3NhZ2UgYm94IHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzDQogICAgICAgIC8vLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cGFyYW0gbmFtZT0iYnV0dG9uIj5UaGUgYnV0dG9ucyB0byBiZSBkaXNwbGF5ZWQ8L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cGFyYW0gbmFtZT0iaWNvbiI+VGhlIG1lc3NhZ2UncyBzZXZlcml0eTwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij5UaGUgZGVmYXVsdCBidXR0b248L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxyZXR1cm5zPlRoZSB1c2VyJ3Mgc2VsZWN0ZWQgYnV0dG9uPC9yZXR1cm5zPg0KICAgICAgICAvL3B1YmxpYyBzdGF0aWMgV1BGQ29udHJvbHMuTWVzc2FnZUJveCBTaG93KHN0cmluZyBtZXNzYWdlLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hCdXR0b24gYnV0dG9uID0gTWVzc2FnZUJveEJ1dHRvbi5PSywNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94SW1hZ2UgaWNvbiA9IE1lc3NhZ2VCb3hJbWFnZS5Ob25lLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuTm9uZSwNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICAvL3sNCiAgICAgICAgLy8gICAgcmV0dXJuIFNob3cNCiAgICAgICAgLy8gICAgKA0KICAgICAgICAvLyAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgLy8gICAgICAgIGRldGFpbHM6IHN0cmluZy5FbXB0eSwNCiAgICAgICAgLy8gICAgICAgIGJ1dHRvbjogYnV0dG9uLA0KICAgICAgICAvLyAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgLy8gICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgIC8vICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAvLyAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgIC8vICAgICk7DQogICAgICAgIC8vfQ0KDQogICAgICAgIC8vLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8vLyBTaG93IHRoZSBtZXNzYWdlIGJveCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycw0KICAgICAgICAvLy8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9ImJ1dHRvbiI+VGhlIGJ1dHRvbnMgdG8gYmUgZGlzcGxheWVkPC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9Imljb24iPlRoZSBtZXNzYWdlJ3Mgc2V2ZXJpdHk8L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+VGhlIGRlZmF1bHQgYnV0dG9uPC9wYXJhbT4NCiAgICAgICAgLy8vLy8gPHBhcmFtIG5hbWU9Im9wdGlvbnMiPk1pc2Mgb3B0aW9uczwvcGFyYW0+DQogICAgICAgIC8vLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgLy9wdWJsaWMgc3RhdGljIFdQRkNvbnRyb2xzLk1lc3NhZ2VCb3ggU2hvdyhXaW5kb3cgb3duZXIsIHN0cmluZyBtZXNzYWdlLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hCdXR0b24gYnV0dG9uID0gTWVzc2FnZUJveEJ1dHRvbi5PSywNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94SW1hZ2UgaWNvbiA9IE1lc3NhZ2VCb3hJbWFnZS5Ob25lLA0KICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuTm9uZSwNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICAvL3sNCiAgICAgICAgLy8gICAgcmV0dXJuIFNob3cNCiAgICAgICAgLy8gICAgKA0KICAgICAgICAvLyAgICAgICAgb3duZXI6IG93bmVyLA0KICAgICAgICAvLyAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgLy8gICAgICAgIGRldGFpbHM6IHN0cmluZy5FbXB0eSwNCiAgICAgICAgLy8gICAgICAgIGJ1dHRvbjogYnV0dG9uLA0KICAgICAgICAvLyAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgLy8gICAgICAgIGRlZmF1bHRSZXN1bHQ6IGRlZmF1bHRSZXN1bHQsDQogICAgICAgIC8vICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAvLyAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgIC8vICAgICk7DQogICAgICAgIC8vfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFNob3cgdGhlIG1lc3NhZ2UgYm94IHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3duZXIiPlRoZSBtZXNzYWdlIGJveCdzIHBhcmVudCB3aW5kb3c8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYnV0dG9uIj5UaGUgYnV0dG9ucyB0byBiZSBkaXNwbGF5ZWQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPlRoZSBtZXNzYWdlJ3Mgc2V2ZXJpdHk8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvbkFjdGlvbiI+5Zue6LCD5Ye95pWwLCDmiafooYwgU2hvdyDmlrnms5XnlKjmiLfngrnlh7vmjInpkq7ml7bkvJrmiafooYzlm57osIPlh73mlbA8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBXUEZDb250cm9scy5NZXNzYWdlQm94IFNob3coV2luZG93IG93bmVyLCBzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveEJ1dHRvbiBidXR0b24gPSBNZXNzYWdlQm94QnV0dG9uLk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94SW1hZ2UgaWNvbiA9IE1lc3NhZ2VCb3hJbWFnZS5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3Rpb248TWVzc2FnZUJveFJlc3VsdD4gb25BY3Rpb24gPSBudWxsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgew0KICAgICAgICAgICAgTWVzc2FnZUJveCBtZXNzYWdlQm94ID0gbmV3IE1lc3NhZ2VCb3gNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGJ1dHRvbjogYnV0dG9uLA0KICAgICAgICAgICAgICAgIGljb246IGljb24sDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIG9uQWN0aW9uOiBvbkFjdGlvbiwNCiAgICAgICAgICAgICAgICBhdXRvQ2xvc2VUaW1lU3BhbjogYXV0b0Nsb3NlVGltZVNwYW4NCiAgICAgICAgICAgICk7DQoNCiAgICAgICAgICAgIG1lc3NhZ2VCb3guU2hvdygpOw0KDQogICAgICAgICAgICByZXR1cm4gbWVzc2FnZUJveDsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFNob3dEaWFsb2cNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBTaG93IHRoZSBtZXNzYWdlIGJveCB3aXRoIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVycw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im1lc3NhZ2UiPlRoZSBtZXNzYWdlIHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRldGFpbHMiPlRoZSBkZXRhaWxzIHBhcnQgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYnV0dG9uIj5UaGUgYnV0dG9ucyB0byBiZSBkaXNwbGF5ZWQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPlRoZSBtZXNzYWdlJ3Mgc2V2ZXJpdHk8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZUJveFJlc3VsdCBTaG93RGlhbG9nKHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgZGV0YWlscyA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94QnV0dG9uIGJ1dHRvbiA9IE1lc3NhZ2VCb3hCdXR0b24uT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hJbWFnZSBpY29uID0gTWVzc2FnZUJveEltYWdlLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93RGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgb3duZXI6IG51bGwsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBkZXRhaWxzLA0KICAgICAgICAgICAgICAgIGJ1dHRvbjogYnV0dG9uLA0KICAgICAgICAgICAgICAgIGljb246IGljb24sDQogICAgICAgICAgICAgICAgZGVmYXVsdFJlc3VsdDogZGVmYXVsdFJlc3VsdCwNCiAgICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zLA0KICAgICAgICAgICAgICAgIGF1dG9DbG9zZVRpbWVTcGFuOiBhdXRvQ2xvc2VUaW1lU3Bhbg0KICAgICAgICAgICAgKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFNob3cgdGhlIG1lc3NhZ2UgYm94IHdpdGggdGhlIHNwZWNpZmllZCBwYXJhbWV0ZXJzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYnV0dG9uIj5UaGUgYnV0dG9ucyB0byBiZSBkaXNwbGF5ZWQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPlRoZSBtZXNzYWdlJ3Mgc2V2ZXJpdHk8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZUJveFJlc3VsdCBTaG93RGlhbG9nKHN0cmluZyBtZXNzYWdlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94QnV0dG9uIGJ1dHRvbiA9IE1lc3NhZ2VCb3hCdXR0b24uT0ssDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hJbWFnZSBpY29uID0gTWVzc2FnZUJveEltYWdlLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveE9wdGlvbnMgb3B0aW9ucyA9IE1lc3NhZ2VCb3hPcHRpb25zLk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwpDQogICAgICAgIHsNCiAgICAgICAgICAgIHJldHVybiBTaG93RGlhbG9nDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBzdHJpbmcuRW1wdHksDQogICAgICAgICAgICAgICAgYnV0dG9uOiBidXR0b24sDQogICAgICAgICAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gU2hvdyB0aGUgbWVzc2FnZSBib3ggd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYnV0dG9uIj5UaGUgYnV0dG9ucyB0byBiZSBkaXNwbGF5ZWQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Imljb24iPlRoZSBtZXNzYWdlJ3Mgc2V2ZXJpdHk8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImRlZmF1bHRSZXN1bHQiPlRoZSBkZWZhdWx0IGJ1dHRvbjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib3B0aW9ucyI+TWlzYyBvcHRpb25zPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJhdXRvQ2xvc2VUaW1lU3BhbiI+5YCS6K6h5pe26Ieq5Yqo5YWz6ZetLCDpu5jorqTkuI3lvIDlkK88L3BhcmFtPg0KICAgICAgICAvLy8gPHJldHVybnM+VGhlIHVzZXIncyBzZWxlY3RlZCBidXR0b248L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgTWVzc2FnZUJveFJlc3VsdCBTaG93RGlhbG9nKFdpbmRvdyBvd25lciwgc3RyaW5nIG1lc3NhZ2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hCdXR0b24gYnV0dG9uID0gTWVzc2FnZUJveEJ1dHRvbi5PSywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveEltYWdlIGljb24gPSBNZXNzYWdlQm94SW1hZ2UuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveFJlc3VsdCBkZWZhdWx0UmVzdWx0ID0gTWVzc2FnZUJveFJlc3VsdC5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGltZVNwYW4/IGF1dG9DbG9zZVRpbWVTcGFuID0gbnVsbCkNCiAgICAgICAgew0KICAgICAgICAgICAgcmV0dXJuIFNob3dEaWFsb2cNCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBvd25lcjogb3duZXIsDQogICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwNCiAgICAgICAgICAgICAgICBkZXRhaWxzOiBzdHJpbmcuRW1wdHksDQogICAgICAgICAgICAgICAgYnV0dG9uOiBidXR0b24sDQogICAgICAgICAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gU2hvdyB0aGUgbWVzc2FnZSBib3ggd2l0aCB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnMNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvd25lciI+VGhlIG1lc3NhZ2UgYm94J3MgcGFyZW50IHdpbmRvdzwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibWVzc2FnZSI+VGhlIG1lc3NhZ2UgdGV4dDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGV0YWlscyI+VGhlIGRldGFpbHMgcGFydCB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJidXR0b24iPlRoZSBidXR0b25zIHRvIGJlIGRpc3BsYXllZDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaWNvbiI+VGhlIG1lc3NhZ2UncyBzZXZlcml0eTwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGVmYXVsdFJlc3VsdCI+VGhlIGRlZmF1bHQgYnV0dG9uPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvcHRpb25zIj5NaXNjIG9wdGlvbnM8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImF1dG9DbG9zZVRpbWVTcGFuIj7lgJLorqHml7boh6rliqjlhbPpl60sIOm7mOiupOS4jeW8gOWQrzwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz5UaGUgdXNlcidzIHNlbGVjdGVkIGJ1dHRvbjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94UmVzdWx0IFNob3dEaWFsb2coV2luZG93IG93bmVyLCBzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZUJveEJ1dHRvbiBidXR0b24gPSBNZXNzYWdlQm94QnV0dG9uLk9LLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94SW1hZ2UgaWNvbiA9IE1lc3NhZ2VCb3hJbWFnZS5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZXNzYWdlQm94UmVzdWx0IGRlZmF1bHRSZXN1bHQgPSBNZXNzYWdlQm94UmVzdWx0Lk5vbmUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2VCb3hPcHRpb25zIG9wdGlvbnMgPSBNZXNzYWdlQm94T3B0aW9ucy5Ob25lLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaW1lU3Bhbj8gYXV0b0Nsb3NlVGltZVNwYW4gPSBudWxsKQ0KICAgICAgICB7DQogICAgICAgICAgICBNZXNzYWdlQm94IG1lc3NhZ2VCb3ggPSBuZXcgTWVzc2FnZUJveA0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBidXR0b24sDQogICAgICAgICAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICBtZXNzYWdlQm94LlNob3dEaWFsb2coKTsNCg0KICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VCb3guTWVzc2FnZUJveFJlc3VsdDsNCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIElOb3RpZnlQcm9wZXJ0eUNoYW5nZWQgTWVtYmVycw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFByb3BlcnR5Q2hhbmdlZA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgZXZlbnQgUHJvcGVydHlDaGFuZ2VkRXZlbnRIYW5kbGVyIFByb3BlcnR5Q2hhbmdlZDsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBPblByb3BlcnR5Q2hhbmdlZA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InByb3BlcnR5TmFtZSI+PC9wYXJhbT4NCiAgICAgICAgcHVibGljIHZvaWQgT25Qcm9wZXJ0eUNoYW5nZWQoc3RyaW5nIHByb3BlcnR5TmFtZSkNCiAgICAgICAgew0KICAgICAgICAgICAgUHJvcGVydHlDaGFuZ2VkRXZlbnRIYW5kbGVyIHRlbXAgPSB0aGlzLlByb3BlcnR5Q2hhbmdlZDsNCiAgICAgICAgICAgIGlmICh0ZW1wICE9IG51bGwpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgdGVtcCh0aGlzLCBuZXcgUHJvcGVydHlDaGFuZ2VkRXZlbnRBcmdzKHByb3BlcnR5TmFtZSkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgICNyZWdpb24gW+W8g+eUqF3ojrflj5blsY/luZXliIbovqjnjocNCg0KICAgICAgICAvL1tPYnNvbGV0ZShtZXNzYWdlOiAi5LiN5L6d6LWWIFdpbkZvcm0g55qEIFN5c3RlbS5XaW5kb3dzLkZvcm1zLmRsbCIpXQ0KICAgICAgICAvL3B1YmxpYyBzdGF0aWMgU3lzdGVtLkRyYXdpbmcuUmVjdGFuZ2xlIFByaW1hcnlTY3JlZW5Xb3JraW5nQXJlYSgpDQogICAgICAgIC8vew0KICAgICAgICAvLyAgICByZXR1cm4gU3lzdGVtLldpbmRvd3MuRm9ybXMuU2NyZWVuLlByaW1hcnlTY3JlZW4uV29ya2luZ0FyZWE7DQogICAgICAgIC8vfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIOWumuaXtuiHquWKqOWFs+mXre+8iCDluLjnlKjkuo7nnIvmnb/mjZXojrflvILluLgg77yJDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g5p+l6K+i54q25oCB6Ze06ZqU5pe26Ze0DQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyByZWFkb25seSBUaW1lU3BhbiBtSW50ZXJ2YWwgPSBUaW1lU3Bhbi5Gcm9tTWlsbGlzZWNvbmRzKDUwMGQpOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOiHquWKqOWFs+mXreaAuyBUaWNrcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBsb25nIG1QbGFuVGlja3MgeyBnZXQ7IHNldDsgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOW9k+WJjeiHquWKqOWFs+mXree0r+iuoSBUaWNrcw0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBsb25nIG1TdW1UaWNrcyB7IGdldDsgc2V0OyB9DQoNCiAgICAgICAgU3lzdGVtLldpbmRvd3MuVGhyZWFkaW5nLkRpc3BhdGNoZXJUaW1lciBtRGlzcGF0Y2hlclRpbWVyIHsgZ2V0OyBzZXQ7IH0NCg0KICAgICAgICB2b2lkIHRpbWVyX1RpY2sob2JqZWN0IHNlbmRlciwgRXZlbnRBcmdzIGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIG1TdW1UaWNrcyA9IG1TdW1UaWNrcyArIG1JbnRlcnZhbC5UaWNrczsNCg0KICAgICAgICAgICAgaWYgKG1QbGFuVGlja3MgPD0gbVN1bVRpY2tzKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGNsb3NlRGlzcGF0Y2hlclRpbWVyKCk7DQoNCiAgICAgICAgICAgICAgICAvLyDlvLnlh7rmj5DnpLrnqpflj6PlkI7vvIznlKjmiLfmnInlj6/og73ngrnlh7vliLAgT3duZXIg55qE5p+Q5Lqb5L2N572u77yM5q2k5pe25Lya5a+86Ie05pys56qX5Y+j5aSE5LqO5aSx5Y6754Sm54K555qE54q25oCB77yMDQogICAgICAgICAgICAgICAgLy8g5Y+I55Sx5LqO5Zyo5aSx5Y6754Sm54K554q25oCB5LiL5bCG5pys56qX5Y+jIENsb3NlIOaOie+8jOS8muWvvOiHtCBPd25lciDkuZ/lpLHljrvnhKbngrnvvIzlr7zoh7TmnIDlsI/ljJYNCiAgICAgICAgICAgICAgICAvLyDmlYXlnKjoh6rliqjlhbPpl63nqpflj6PliY3noa7kv50gSXNGb2N1c2VkIOS4uiB0cnVlDQogICAgICAgICAgICAgICAgaWYgKHRoaXMuSXNGb2N1c2VkID09IGZhbHNlKSB7IHRoaXMuRm9jdXMoKTsgfQ0KICAgICAgICAgICAgICAgIHRoaXMuQ2xvc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGVsc2UNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICB0aGlzLk93bmVyLkRpc3BhdGNoZXIuSW52b2tlKG5ldyBBY3Rpb24oKCkgPT4NCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIGxibEF1dG9DbG9zZS5UZXh0ID0gVG9TdHJpbmdBZHZTaW1wbGUobmV3IFRpbWVTcGFuKG1QbGFuVGlja3MgLSBtU3VtVGlja3MpKTsNCiAgICAgICAgICAgICAgICB9KSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICB2b2lkIGNsb3NlRGlzcGF0Y2hlclRpbWVyKCkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKG1EaXNwYXRjaGVyVGltZXIgIT0gbnVsbCAmJiBtRGlzcGF0Y2hlclRpbWVyLklzRW5hYmxlZCA9PSB0cnVlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIG1EaXNwYXRjaGVyVGltZXIuU3RvcCgpOw0KICAgICAgICAgICAgICAgIG1EaXNwYXRjaGVyVGltZXIuVGljayAtPSB0aW1lcl9UaWNrOw0KICAgICAgICAgICAgICAgIG1EaXNwYXRjaGVyVGltZXIgPSBudWxsOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gVGltZVNwYW7ovazmjaLmloflrZfkv6Hmga8g77yIIOS4jeWQq+avq+enkuS/oeaBryDvvIkNCiAgICAgICAgLy8vIOaLt+i0neiHqiBVdGlsLkhvd2VzRE9NT1xDb21tb25FeHRlbnNpb25zXFRpbWVTcGFuRXh0ZW5zaW9uLmNzDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idHMiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIHB1YmxpYyBzdGF0aWMgc3RyaW5nIFRvU3RyaW5nQWR2U2ltcGxlKFRpbWVTcGFuIHRzKQ0KICAgICAgICB7DQogICAgICAgICAgICBzdHJpbmcgciA9IHN0cmluZy5FbXB0eTsNCg0KICAgICAgICAgICAgaWYgKHRzLkRheXMgPiAwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHIgKz0gJCJ7dHMuRGF5c30g5aSpIjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgaWYgKHRzLkhvdXJzID4gMCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByICs9ICQie3RzLkhvdXJzfSDlsI/ml7YiOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAodHMuTWludXRlcyA+IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgciArPSAkInt0cy5NaW51dGVzfSDliIYiOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAodHMuU2Vjb25kcyA+IDApDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgciArPSAkInt0cy5TZWNvbmRzfSDnp5IiOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkocikpDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgciA9ICIwIOenkiI7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vaWYgKHRzLk1pbGxpc2Vjb25kcyA+IDApDQogICAgICAgICAgICAvL3sNCiAgICAgICAgICAgIC8vICAgIHIgKz0gJCJ7dHMuTWlsbGlzZWNvbmRzfeavq+enkiI7DQogICAgICAgICAgICAvL30NCg0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgI3JlZ2lvbiBFeGNlcHRpb24gR2V0SW5mbw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIOWIpOaWreaYr+WQpuS4uiBCdXNpbmVzc0V4Y2VwdGlvbg0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImUiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+DQogICAgICAgIHN0YXRpYyBib29sIElzQnVzaW5lc3NFeGNlcHRpb24oRXhjZXB0aW9uIGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIHN0cmluZyBtc2cgPSBlLk1lc3NhZ2U7DQoNCiAgICAgICAgICAgIGludCBpbmRleE9mX2NTdGFydCA9IG1zZy5JbmRleE9mKGNTdGFydCk7DQogICAgICAgICAgICBpbnQgaW5kZXhPZl9jRW5kID0gbXNnLkluZGV4T2YoY0VuZCk7DQoNCiAgICAgICAgICAgIGJvb2wgciA9IGluZGV4T2ZfY1N0YXJ0ID49IDAgJiYgaW5kZXhPZl9jRW5kID4gaW5kZXhPZl9jU3RhcnQ7DQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGNvbnN0IHN0cmluZyBjU3RhcnQgPSAiXHUwMDAyIjsNCg0KICAgICAgICBjb25zdCBzdHJpbmcgY0VuZCA9ICJcdTAwMDMiOw0KDQogICAgICAgIHN0YXRpYyB2b2lkIEdldEV4Y2VwdGlvbkZ1bGxJbmZvKEV4Y2VwdGlvbiBleCwgU3RyaW5nQnVpbGRlciBzYiwgaW50IGxldmVsID0gMSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHNiLlRvU3RyaW5nKCkpID09IGZhbHNlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHNiLkFwcGVuZExpbmUoIioqKioqKioqKioqKioqIElubmVyIEV4Y2VwdGlvbiAiICsgbGV2ZWwgKyAiKioqKioqKioqKioqKioiKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgc2IuQXBwZW5kTGluZShleC5NZXNzYWdlICsgIlxyXG4iICsgZXguU3RhY2tUcmFjZSk7DQoNCiAgICAgICAgICAgIGlmIChleC5Jbm5lckV4Y2VwdGlvbiAhPSBudWxsKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGxldmVsID0gbGV2ZWwgKyAxOw0KICAgICAgICAgICAgICAgIEdldEV4Y2VwdGlvbkZ1bGxJbmZvKGV4LklubmVyRXhjZXB0aW9uLCBzYiwgbGV2ZWwpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgc3RhdGljIHN0cmluZyBFeGNlcHRpb25HZXRJbmZvKEV4Y2VwdGlvbiBlKQ0KICAgICAgICB7DQogICAgICAgICAgICBpZiAoSXNCdXNpbmVzc0V4Y2VwdGlvbihlKSA9PSB0cnVlKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vc3RyaW5nIG1zZyA9IGUuTWVzc2FnZTsNCg0KICAgICAgICAgICAgICAgIC8vaW50IGNTdGFydEluZGV4ID0gbXNnLkluZGV4T2YoY1N0YXJ0KSArIDE7DQogICAgICAgICAgICAgICAgLy9pbnQgY0VuZEluZGV4ID0gbXNnLkluZGV4T2YoY0VuZCk7DQoNCiAgICAgICAgICAgICAgICAvL3JldHVybiBtc2cuU3Vic3RyaW5nKGNTdGFydEluZGV4LCBjRW5kSW5kZXggLSBjU3RhcnRJbmRleCk7DQoNCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nLkVtcHR5OyAvLyDkuJrliqHpgLvovpHlvILluLjml6DpnIDmmL7npLogRGV0YWlsDQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7DQogICAgICAgICAgICAgICAgR2V0RXhjZXB0aW9uRnVsbEluZm8oZSwgc2IpOw0KICAgICAgICAgICAgICAgIHJldHVybiBzYi5Ub1N0cmluZygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgI2VuZHJlZ2lvbg0KDQogICAgICAgIFdpbmRvdyBnZXRDdXJyZW50V2luZG93KCkNCiAgICAgICAgew0KICAgICAgICAgICAgV2luZG93IHIgPSBBcHBsaWNhdGlvbi5DdXJyZW50LldpbmRvd3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuT2ZUeXBlPFdpbmRvdz4oKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5XaGVyZShpID0+IGkuSXNBY3RpdmUgPT0gdHJ1ZSkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuRmlyc3RPckRlZmF1bHQoKTsNCg0KICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICByID0gQXBwbGljYXRpb24uQ3VycmVudC5NYWluV2luZG93Ow0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgICNyZWdpb24gW0RQXSDor6bmg4UNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBbRFBdIOivpuaDhQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERlcGVuZGVuY3lQcm9wZXJ0eSBEZXRhaWxzRXhwYW5kZXJfSXNFeHBhbmRlclByb3BlcnR5ID0gRGVwZW5kZW5jeVByb3BlcnR5LlJlZ2lzdGVyDQogICAgICAgICgNCiAgICAgICAgICAgIG5hbWU6ICJEZXRhaWxzRXhwYW5kZXJfSXNFeHBhbmRlciIsDQogICAgICAgICAgICBwcm9wZXJ0eVR5cGU6IHR5cGVvZihib29sKSwNCiAgICAgICAgICAgIG93bmVyVHlwZTogdHlwZW9mKE1lc3NhZ2VCb3gpLA0KICAgICAgICAgICAgdmFsaWRhdGVWYWx1ZUNhbGxiYWNrOiBudWxsLCAvLyBuZXcgVmFsaWRhdGVWYWx1ZUNhbGxiYWNrKCh0b1ZhbGlkYXRlKSA9PiB7IHJldHVybiB0cnVlOyB9KSwNCiAgICAgICAgICAgIHR5cGVNZXRhZGF0YTogbmV3IFByb3BlcnR5TWV0YWRhdGENCiAgICAgICAgICAgICgNCiAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsDQogICAgICAgICAgICAgICAgcHJvcGVydHlDaGFuZ2VkQ2FsbGJhY2s6IG9uRGV0YWlsc0V4cGFuZGVyX0lzRXhwYW5kZXJfUHJvcGVydHlDaGFuZ2VkQ2FsbGJhY2ssDQogICAgICAgICAgICAgICAgY29lcmNlVmFsdWVDYWxsYmFjazogbnVsbA0KICAgICAgICAgICAgKQ0KICAgICAgICApOw0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIFtEUF0g6K+m5oOFDQogICAgICAgIC8vLyA8L3N1bW1hcnk+DQogICAgICAgIHB1YmxpYyBib29sIERldGFpbHNFeHBhbmRlcl9Jc0V4cGFuZGVyDQogICAgICAgIHsNCiAgICAgICAgICAgIGdldCB7IHJldHVybiAoYm9vbClHZXRWYWx1ZShEZXRhaWxzRXhwYW5kZXJfSXNFeHBhbmRlclByb3BlcnR5KTsgfQ0KICAgICAgICAgICAgc2V0IHsgU2V0VmFsdWUoRGV0YWlsc0V4cGFuZGVyX0lzRXhwYW5kZXJQcm9wZXJ0eSwgdmFsdWUpOyB9DQogICAgICAgIH0NCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBbRFBdIOivpuaDhQ0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImQiPjwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZSI+PC9wYXJhbT4NCiAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIG9uRGV0YWlsc0V4cGFuZGVyX0lzRXhwYW5kZXJfUHJvcGVydHlDaGFuZ2VkQ2FsbGJhY2soRGVwZW5kZW5jeU9iamVjdCBkLCBEZXBlbmRlbmN5UHJvcGVydHlDaGFuZ2VkRXZlbnRBcmdzIGUpDQogICAgICAgIHsNCiAgICAgICAgICAgIGlmIChkIGlzIE1lc3NhZ2VCb3ggdGFyZ2V0KQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIGlmICgoYm9vbCllLk5ld1ZhbHVlKSAvLyB0cnVlDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZ01haW4uUm93RGVmaW5pdGlvbnMuUmVtb3ZlQXQoMCk7DQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5nTWFpbi5Sb3dEZWZpbml0aW9ucy5SZW1vdmVBdCgwKTsNCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdNYWluLlJvd0RlZmluaXRpb25zLlJlbW92ZUF0KDApOw0KDQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5nTWFpbi5Sb3dEZWZpbml0aW9ucy5BZGQobmV3IFJvd0RlZmluaXRpb24oKSB7IEhlaWdodCA9IEdyaWRMZW5ndGguQXV0bywgTWluSGVpZ2h0ID0gNjAgfSk7DQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5nTWFpbi5Sb3dEZWZpbml0aW9ucy5BZGQobmV3IFJvd0RlZmluaXRpb24oKSB7IEhlaWdodCA9IG5ldyBHcmlkTGVuZ3RoKDMsIEdyaWRVbml0VHlwZS5QaXhlbCkgfSk7DQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5nTWFpbi5Sb3dEZWZpbml0aW9ucy5BZGQobmV3IFJvd0RlZmluaXRpb24oKSB7IEhlaWdodCA9IEdyaWRMZW5ndGguQXV0bywgTWluSGVpZ2h0ID0gNDAgfSk7DQoNCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdyaWRTcGxpdHRlcjAuVmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuVmlzaWJsZTsNCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdyaWRTcGxpdHRlcjEuVmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuVmlzaWJsZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZWxzZSAvLyBmYWxzZQ0KICAgICAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdNYWluLlJvd0RlZmluaXRpb25zLlJlbW92ZUF0KDApOw0KICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZ01haW4uUm93RGVmaW5pdGlvbnMuUmVtb3ZlQXQoMCk7DQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5nTWFpbi5Sb3dEZWZpbml0aW9ucy5SZW1vdmVBdCgwKTsNCg0KICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZ01haW4uUm93RGVmaW5pdGlvbnMuQWRkKG5ldyBSb3dEZWZpbml0aW9uKCkgeyBIZWlnaHQgPSBHcmlkTGVuZ3RoLkF1dG8sIE1pbkhlaWdodCA9IDYwIH0pOw0KICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZ01haW4uUm93RGVmaW5pdGlvbnMuQWRkKG5ldyBSb3dEZWZpbml0aW9uKCkgeyBIZWlnaHQgPSBuZXcgR3JpZExlbmd0aCgzLCBHcmlkVW5pdFR5cGUuUGl4ZWwpIH0pOw0KICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZ01haW4uUm93RGVmaW5pdGlvbnMuQWRkKG5ldyBSb3dEZWZpbml0aW9uKCkgeyBIZWlnaHQgPSBHcmlkTGVuZ3RoLkF1dG8sIE1pbkhlaWdodCA9IDQwIH0pOw0KDQogICAgICAgICAgICAgICAgICAgIHRhcmdldC5ncmlkU3BsaXR0ZXIwLlZpc2liaWxpdHkgPSBWaXNpYmlsaXR5LkNvbGxhcHNlZDsNCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmdyaWRTcGxpdHRlcjEuVmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuQ29sbGFwc2VkOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICNlbmRyZWdpb24NCg0KICAgICAgICAjcmVnaW9uIFtEUF0gRXh0cmFDb250ZW50IC0g6Ieq5a6a5LmJ55WM6Z2i77yM5Y+v5Lul5Lyg5YWlIENvbnRlbnRDb250cm9sIOadpeWunueOsOS4gOS6m+eugOWNleeahOi+k+WFpeehruiupOeVjOmdou+8jOS+i+WmgiDotKblj7flr4bnoIHvvIwg5omT5Y2w5pWw6YePDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8gW0RQXSBFeHRyYUNvbnRlbnQNCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIHN0YXRpYyByZWFkb25seSBEZXBlbmRlbmN5UHJvcGVydHkgRXh0cmFDb250ZW50UHJvcGVydHkgPSBEZXBlbmRlbmN5UHJvcGVydHkuUmVnaXN0ZXINCiAgICAgICAgKA0KICAgICAgICAgICAgbmFtZTogIkV4dHJhQ29udGVudCIsDQogICAgICAgICAgICBwcm9wZXJ0eVR5cGU6IHR5cGVvZihvYmplY3QpLA0KICAgICAgICAgICAgb3duZXJUeXBlOiB0eXBlb2YoTWVzc2FnZUJveCksDQogICAgICAgICAgICB2YWxpZGF0ZVZhbHVlQ2FsbGJhY2s6IG5ldyBWYWxpZGF0ZVZhbHVlQ2FsbGJhY2soKHRvVmFsaWRhdGUpID0+DQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgaWYgKHRvVmFsaWRhdGUgaXMgbnVsbCkNCiAgICAgICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICBpZiAodG9WYWxpZGF0ZSBpcyBDb250ZW50Q29udHJvbCBjYyAmJiBjYy5EYXRhQ29udGV4dCBpcyBJRGF0YUVycm9ySW5mbyBkYXRhQ29udGV4dCkNCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgICAgICAgICBlbHNlDQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSksDQogICAgICAgICAgICB0eXBlTWV0YWRhdGE6IG5ldyBGcmFtZXdvcmtQcm9wZXJ0eU1ldGFkYXRhDQogICAgICAgICAgICAoDQogICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiBudWxsLA0KICAgICAgICAgICAgICAgIHByb3BlcnR5Q2hhbmdlZENhbGxiYWNrOiBudWxsLA0KICAgICAgICAgICAgICAgIGNvZXJjZVZhbHVlQ2FsbGJhY2s6IG51bGwNCiAgICAgICAgICAgICkNCiAgICAgICAgKTsNCg0KICAgICAgICAvLy8gPHN1bW1hcnk+DQogICAgICAgIC8vLyBFeHRyYUNvbnRlbnQgLSDoh6rlrprkuYnnlYzpnaLvvIzlj6/ku6XkvKDlhaUgQ29udGVudENvbnRyb2wg5p2l5a6e546w5LiA5Lqb566A5Y2V55qE6L6T5YWl56Gu6K6k55WM6Z2i77yM5L6L5aaCIOi0puWPt+Wvhuegge+8jCDmiZPljbDmlbDph48NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgcHVibGljIG9iamVjdCBFeHRyYUNvbnRlbnQNCiAgICAgICAgew0KICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIChvYmplY3QpR2V0VmFsdWUoRXh0cmFDb250ZW50UHJvcGVydHkpOyB9DQogICAgICAgICAgICBzZXQgeyBTZXRWYWx1ZShFeHRyYUNvbnRlbnRQcm9wZXJ0eSwgdmFsdWUpOyB9DQogICAgICAgIH0NCg0KICAgICAgICAjZW5kcmVnaW9uDQoNCiAgICAgICAgLy8vIDxzdW1tYXJ5Pg0KICAgICAgICAvLy8g55So5LqOIE1lc3NhZ2VCb3g0VXNlckRlZmluZUNjLCDnqIvluo/lkZjmoLnmja7kuJrliqHpgLvovpHkvKDpgJLmmK/lkKblhbPpl60gTWVzc2FnZUJveA0KICAgICAgICAvLy8gPC9zdW1tYXJ5Pg0KICAgICAgICBwdWJsaWMgRnVuYzxNZXNzYWdlQm94LCBNZXNzYWdlQm94UmVzdWx0LCBib29sPiBPbkZ1bmMgeyBnZXQ7IHNldDsgfQ0KDQogICAgICAgIC8vLyA8c3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhPuiOt+WPlueql+S9k++8iCDnlKjkuo7kvKDlhaUgRXh0cmFDb250ZW50IO+8iTwvcGFyYT4NCiAgICAgICAgLy8vIDxwYXJhPui/lOWbniBPSyAvIENhbmNlbDwvcGFyYT4NCiAgICAgICAgLy8vIDwvc3VtbWFyeT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJtZXNzYWdlIj5UaGUgbWVzc2FnZSB0ZXh0PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZXRhaWxzIj5UaGUgZGV0YWlscyBwYXJ0IHRleHQ8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im93bmVyIj5UaGUgbWVzc2FnZSBib3gncyBwYXJlbnQgd2luZG93PC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJidXR0b24iPum7mOiupCBPS0NhbmNlbDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iaWNvbiI+6buY6K6kIEluZm9ybWF0aW9uPC9wYXJhbT4NCiAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJkZWZhdWx0UmVzdWx0Ij7pu5jorqTnu5PmnpzkuLogT0s8L3BhcmFtPg0KICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im9wdGlvbnMiPk1pc2Mgb3B0aW9uczwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ib25GdW5jIj7lm57osIPlh73mlbAsIOaJp+ihjCBTaG93IOaWueazleeUqOaIt+eCueWHu+aMiemSruaXtuS8muaJp+ihjOWbnuiwg+WHveaVsDwvcGFyYW0+DQogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYXV0b0Nsb3NlVGltZVNwYW4iPuWAkuiuoeaXtuiHquWKqOWFs+mXrSwg6buY6K6k5LiN5byA5ZCvPC9wYXJhbT4NCiAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4NCiAgICAgICAgcHVibGljIHN0YXRpYyBNZXNzYWdlQm94IEdldE1lc3NhZ2VCb3g0VXNlckRlZmluZUNjDQogICAgICAgICgNCiAgICAgICAgICAgIHN0cmluZyBtZXNzYWdlLA0KICAgICAgICAgICAgc3RyaW5nIGRldGFpbHMgPSAiIiwNCiAgICAgICAgICAgIFdpbmRvdyBvd25lciA9IG51bGwsDQogICAgICAgICAgICBNZXNzYWdlQm94QnV0dG9uIGJ1dHRvbiA9IE1lc3NhZ2VCb3hCdXR0b24uT0tDYW5jZWwsDQogICAgICAgICAgICBNZXNzYWdlQm94SW1hZ2UgaWNvbiA9IE1lc3NhZ2VCb3hJbWFnZS5JbmZvcm1hdGlvbiwNCiAgICAgICAgICAgIE1lc3NhZ2VCb3hSZXN1bHQgZGVmYXVsdFJlc3VsdCA9IE1lc3NhZ2VCb3hSZXN1bHQuT0ssDQogICAgICAgICAgICBNZXNzYWdlQm94T3B0aW9ucyBvcHRpb25zID0gTWVzc2FnZUJveE9wdGlvbnMuTm9uZSwNCiAgICAgICAgICAgIEZ1bmM8TWVzc2FnZUJveCwgTWVzc2FnZUJveFJlc3VsdCwgYm9vbD4gb25GdW5jID0gbnVsbCwNCiAgICAgICAgICAgIFRpbWVTcGFuPyBhdXRvQ2xvc2VUaW1lU3BhbiA9IG51bGwNCiAgICAgICAgKQ0KICAgICAgICB7DQogICAgICAgICAgICBNZXNzYWdlQm94IG1lc3NhZ2VCb3ggPSBuZXcgTWVzc2FnZUJveA0KICAgICAgICAgICAgKA0KICAgICAgICAgICAgICAgIG93bmVyOiBvd25lciwNCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLA0KICAgICAgICAgICAgICAgIGRldGFpbHM6IGRldGFpbHMsDQogICAgICAgICAgICAgICAgYnV0dG9uOiBidXR0b24sDQogICAgICAgICAgICAgICAgaWNvbjogaWNvbiwNCiAgICAgICAgICAgICAgICBkZWZhdWx0UmVzdWx0OiBkZWZhdWx0UmVzdWx0LA0KICAgICAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnMsDQogICAgICAgICAgICAgICAgYXV0b0Nsb3NlVGltZVNwYW46IGF1dG9DbG9zZVRpbWVTcGFuDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICBtZXNzYWdlQm94Lk9uRnVuYyA9IG9uRnVuYzsNCg0KICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VCb3g7DQogICAgICAgIH0NCg0KICAgIH0NCn0=";
                    _LongMsg = Encoding.UTF8.GetString(Convert.FromBase64String(base64Str));
                }
                return _LongMsg;
            }
        }

        public FrmTest_MessageBox()
        {
            InitializeComponent();
        }

        private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            string key = this.ToString();
            WPFControls.MessageBox.AddUserDefineFontSize(key, e.NewValue);
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string m = "Info";

            var dr = WPFControls.MessageBox.ShowInformationDialog(owner: this, m);
            System.Diagnostics.Debug.WriteLine(dr);

            dr = WPFControls.MessageBox.ShowErrorDialog(owner: this, m);
            System.Diagnostics.Debug.WriteLine(dr);

            dr = WPFControls.MessageBox.ShowWarningDialog(owner: this, m);
            System.Diagnostics.Debug.WriteLine(dr);

            dr = WPFControls.MessageBox.ShowConfirmDialog(owner: this, m);
            System.Diagnostics.Debug.WriteLine(dr);

            dr = WPFControls.MessageBox.ShowQuestionDialog(owner: this, m);
            System.Diagnostics.Debug.WriteLine(dr);

            dr = WPFControls.MessageBox.ShowQuestionDialog(owner: this, m, showCancel: true);
            System.Diagnostics.Debug.WriteLine(dr);

            //// 尽量使用上面的方式

            //dr = WPFControls.MessageBox.ShowDialog
            //(
            //    owner: this,
            //    message: "确定",
            //    button: MessageBoxButton.YesNoCancel,
            //    icon: MessageBoxImage.Question,
            //    defaultResult: MessageBoxResult.Yes, // 重点, 命中 Yes No Cancel, 因为默认值是 None
            //    options: MessageBoxOptions.None,
            //    autoCloseTimeSpan: null
            //);
        }

        private void Button_Click_5(object sender, RoutedEventArgs e)
        {
            var m = this.LongMsg;

            WPFControls.MessageBox.ShowInformationDialog(owner: this, m);

            WPFControls.MessageBox.ShowErrorDialog(owner: this, m);

            WPFControls.MessageBox.ShowWarningDialog(owner: this, m);

            WPFControls.MessageBox.ShowConfirmDialog(owner: this, m);

            WPFControls.MessageBox.ShowQuestionDialog(owner: this, m);

            WPFControls.MessageBox.ShowDialog(owner: this, message: m, MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            string m = "一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五";
            string d = "一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五一二三四五";

            WPFControls.MessageBox.ShowInformationDialog
            (
                owner: this,
                message: m,
                details: d
            );

            WPFControls.MessageBox.ShowQuestionDialog
            (
                owner: this,
                message: m,
                details: d
            );
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            string d = LongMsg;

            WPFControls.MessageBox.ShowInformationDialog
            (
                owner: this,
                message: d,
                details: d
            );

            WPFControls.MessageBox.ShowInformationDialog
            (
                owner: this,
                message: d,
                details: d
            );
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            WPFControls.MessageBox.ShowDialog(owner: this, "1", "1", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
            WPFControls.MessageBox.ShowDialog(owner: this, "1", "1", MessageBoxButton.YesNo, MessageBoxImage.Question);
            WPFControls.MessageBox.ShowDialog(owner: this, "1", "1", MessageBoxButton.OK, MessageBoxImage.Question);
        }

        private void Button_Click_6(object sender, RoutedEventArgs e)
        {
            string m = "无法访问数据库";
            string d = Encoding.UTF8.GetString(Convert.FromBase64String("aW1wb3J0IGFuZHJvaWQuYXBwLkFjdGl2aXR5TWFuYWdlcjsNCmltcG9ydCBhbmRyb2lkLmFwcC5TZXJ2aWNlOw0KaW1wb3J0IGFuZHJvaWQuY29udGVudC5Db250ZXh0Ow0KaW1wb3J0IGFuZHJvaWQuY29udGVudC5JbnRlbnQ7DQppbXBvcnQgYW5kcm9pZC5vcy5IYW5kbGVyOw0KaW1wb3J0IGFuZHJvaWQub3MuSUJpbmRlcjsNCmltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOw0KDQppbXBvcnQgamF2YS51dGlsLkxpc3Q7DQoNCi8qKg0KICogQ3JlYXRlZCBieSBnb25nd3Egb24gMjAxNy82LzE3IDAwMTcuDQogKi8NCg0KcHVibGljIGNsYXNzIE15U2VydmljZSBleHRlbmRzIFNlcnZpY2Ugew0KICAgIEFjdGl2aXR5TWFuYWdlciBhY3Rpdml0eU1hbmFnZXIgPSBudWxsOw0KICAgIEhhbmRsZXIgaGFuZGxlciA9IG5ldyBIYW5kbGVyKCk7DQogICAgU3RyaW5nIGFjdGl2aXR5TmFtZSA9IG51bGw7DQogICAgU3RyaW5nIGFjdGl2aXR5X2xhc3QgPSBudWxsOw0KICAgIFJ1bm5hYmxlIHJ1bm5hYmxlID0gbmV3IFJ1bm5hYmxlKCkgew0KDQogICAgICAgIEBPdmVycmlkZQ0KICAgICAgICBwdWJsaWMgdm9pZCBydW4oKSB7DQogICAgICAgICAgICBMaXN0PEFjdGl2aXR5TWFuYWdlci5SdW5uaW5nVGFza0luZm8+IHJ1bm5pbmdUYXNrSW5mbyA9IGFjdGl2aXR5TWFuYWdlci5nZXRSdW5uaW5nVGFza3MoMSk7DQogICAgICAgICAgICBhY3Rpdml0eU5hbWUgPSAocnVubmluZ1Rhc2tJbmZvLmdldCgwKS50b3BBY3Rpdml0eSkudG9TdHJpbmcoKTsNCiAgICAgICAgICAgIGlmICghKGFjdGl2aXR5TmFtZS5lcXVhbHMoYWN0aXZpdHlfbGFzdCkpKSB7DQogICAgICAgICAgICAgICAgTG9nLmUoIkFjdGl2aXR5TWFuYWdlcjogIiwgIuW9k+WJjWFjdGl2aXR55pivLS0tLT4iICsgYWN0aXZpdHlOYW1lKTsNCiAgICAgICAgICAgICAgICBhY3Rpdml0eV9sYXN0ID0gYWN0aXZpdHlOYW1lOw0KDQogICAgICAgICAgICB9DQogICAgICAgICAgICBoYW5kbGVyLnBvc3REZWxheWVkKHJ1bm5hYmxlLCAxMCk7DQogICAgICAgIH0NCiAgICB9Ow0KDQogICAgQE92ZXJyaWRlDQogICAgcHVibGljIGludCBvblN0YXJ0Q29tbWFuZChJbnRlbnQgaW50ZW50LCBpbnQgZmxhZ3MsIGludCBzdGFydElkKSB7DQogICAgICAgIGhhbmRsZXIucG9zdERlbGF5ZWQocnVubmFibGUsIDEwKTsNCiAgICAgICAgcmV0dXJuIHN1cGVyLm9uU3RhcnRDb21tYW5kKGludGVudCwgZmxhZ3MsIHN0YXJ0SWQpOw0KICAgIH0NCg0KICAgIEBPdmVycmlkZQ0KICAgIHB1YmxpYyB2b2lkIG9uQ3JlYXRlKCkgew0KICAgICAgICBzdXBlci5vbkNyZWF0ZSgpOw0KICAgICAgICBhY3Rpdml0eU1hbmFnZXIgPSAoQWN0aXZpdHlNYW5hZ2VyKSBnZXRTeXN0ZW1TZXJ2aWNlKENvbnRleHQuQUNUSVZJVFlfU0VSVklDRSk7DQogICAgfQ0KDQogICAgQE92ZXJyaWRlDQogICAgcHVibGljIElCaW5kZXIgb25CaW5kKEludGVudCBhcmcwKSB7DQogICAgICAgIHJldHVybiBudWxsOw0KICAgIH0NCg0KICAgIEBPdmVycmlkZQ0KICAgIHB1YmxpYyB2b2lkIG9uRGVzdHJveSgpIHsNCiAgICAgICAgaGFuZGxlci5yZW1vdmVDYWxsYmFja3MocnVubmFibGUpOw0KICAgIH0NCn0NCuKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlOKAlA0K54mI5p2D5aOw5piO77ya5pys5paH5Li6Q1NETuWNmuS4u+OAjGFuZHJvaWRfY21vc+OAjeeahOWOn+WIm+aWh+eroO+8jOmBteW+qkNDIDQuMCBCWS1TQeeJiOadg+WNj+iuru+8jOi9rOi9veivt+mZhOS4iuWOn+aWh+WHuuWkhOmTvuaOpeWPiuacrOWjsOaYjuOAgg0K5Y6f5paH6ZO+5o6l77yaaHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FuZHJvaWRfY21vcy9hcnRpY2xlL2RldGFpbHMvNzMzODI1NzM="));

            WPFControls.MessageBox.ShowDialog(owner: this, m, d, MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
        }

        private void Button_Test_DefaultMessageBoxResult(object sender, RoutedEventArgs e)
        {
            // 模仿 MessageBox 的默认宣州 Cancel
            var dr0 = MessageBox.Show("确认关闭", "Tips", icon: MessageBoxImage.Question, button: MessageBoxButton.OKCancel, defaultResult: MessageBoxResult.Cancel);
            System.Diagnostics.Debug.WriteLine(dr0);


            var dr = WPFControls.MessageBox.ShowConfirmDialog("确认关闭", defaultResult: MessageBoxResult.Cancel);
            System.Diagnostics.Debug.WriteLine(dr);

        }

        #region Extra Content

        private void Button_ExtraContent(object sender, RoutedEventArgs e)
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入需要补打的数量"
            );

            var content = new WPFControls.MessageBoxExtraContent.CcTextBox() { Title = "打印数量" };
            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel();
            content.DataContext = vm; // ** 重点 **

            // 对 预设值 进行赋值
            vm.Value = "10"; // 预设补打 10 张

            // 编写校验业务逻辑
            vm.CheckValueLogic_UserDefine = new Func<string>(() =>
            {
                string errorMsg = string.Empty;

                if (vm.Value is null)
                {
                    return "空值";
                }

                if (int.TryParse(vm.Value.ToString(), out int qty) == false)
                {
                    return "数值校验错误";
                }

                if (qty <= 0)
                {
                    return "数值校验错误";
                }

                return errorMsg;
            });

            msgBox.OnFunc = (target, result) =>
            {
                var view = target.ExtraContent as WPFControls.MessageBoxExtraContent.CcTextBox;
                var viewModel = view.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel;

                int qty = int.Parse(vm.Value.ToString());
                if (qty <= 10)
                {
                    viewModel.TextBox_IsFocusSelectAll = true;
                    return false;
                }
                return true;
            };


            msgBox.ExtraContent = content;

            msgBox.ShowDialog(); // !!! 注意不能直接用ShowDialog的返回结果, 需要用对象的 MessageBoxResult 属性

            if (msgBox.MessageBoxResult == MessageBoxResult.OK)
            {
                var data = content.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel;
                MessageBox.Show(Util.JsonUtils.SerializeObject(data.Value));
            }
        }

        private void Button_ExtraContent_CcTextarea(object sender, RoutedEventArgs e)
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc("请输入你的的建议");
            var cc = new WPFControls.MessageBoxExtraContent.CcTextarea() { Title = "填写你的建议" };
            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel();
            cc.DataContext = vm; // ** 重点 **

            // 编写校验业务逻辑
            vm.CheckValueLogic_UserDefine = new Func<string>(() =>
            {
                string r = string.Empty;

                if (vm.Value == null || vm.Value.ToString().IndexOf("建议") < 0)
                {
                    r = "必须含有 建议 这两个字";
                }

                return r;
            });

            msgBox.OnFunc = (target, result) =>
            {
                var view = target.ExtraContent as WPFControls.MessageBoxExtraContent.CcTextarea;
                var viewModel = view.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel;

                string jianyi = vm.Value.ToString();
                if (jianyi.Length <= 10)
                {
                    viewModel.TextBox_IsFocusSelectAll = true;
                    return false;
                }
                return true;
            };

            msgBox.ExtraContent = cc;
            msgBox.ShowDialog(); // !!! 注意不能直接用ShowDialog的返回结果, 需要用对象的 MessageBoxResult 属性

            if (msgBox.MessageBoxResult == MessageBoxResult.OK)
            {
                MessageBox.Show(vm.Value.ToString());
            }
        }

        private void Button_ExtraContent_CcDatePicker(object sender, RoutedEventArgs e)
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc("请选择入住日期");
            var cc = new WPFControls.MessageBoxExtraContent.CcDatePicker()
            // { Title = "填写你的建议" }
            ;
            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.SingleItemViewModel();
            cc.DataContext = vm; // ** 重点 **

            // 编写校验业务逻辑
            vm.CheckValueLogic_UserDefine = new Func<string>(() =>
            {
                string r = string.Empty;

                if (vm.Value == null)
                {
                    r = "请选择入住日期";
                }
                else if
                (
                    DateTime.TryParse(vm.Value.ToString(), out DateTime dt) == false ||
                    dt.Date <= DateTime.Now.Date
                )
                {
                    r = "日期不能晚于明天";
                }

                return r;
            });

            msgBox.ExtraContent = cc;
            msgBox.ShowDialog(); // !!! 注意不能直接用ShowDialog的返回结果, 需要用对象的 MessageBoxResult 属性

            if (msgBox.MessageBoxResult == MessageBoxResult.OK)
            {
                MessageBox.Show(vm.Value.ToString());
            }
        }

        private void Button_ExtraContent_AccountPassword(object sender, RoutedEventArgs e)
        {
            // abp(); // 已过时, 改用下面代码

            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel();
            var content = new WPFControls.MessageBoxExtraContent.CcAccountPassword(vm);

            Func<WPFControls.MessageBox, MessageBoxResult, bool> onFunc = (frm, r) =>
            {
                if (r != MessageBoxResult.OK)
                {
                    return true; // 用户点击了取消, 返回 true 关闭 msgBox
                }

                var u = content.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel;
                if (u.LoginAccount == "a2222" && u.Password == "2")
                {
                    WPFControls.MessageBox.ShowInformationDialog(frm, "账号密码正确");
                    return true;
                }
                else
                {
                    WPFControls.MessageBox.ShowErrorDialog(frm, "账号密码错误, 账号 a2222, 密码 2");
                    u.LoginAccount_IsFocusSelectAll = true;
                    u.Password = string.Empty;
                    return false;
                }
            };


            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入管理员账号密码",
                "Hello\r\nWorld",
                onFunc: onFunc
            );

            msgBox.ExtraContent = content;
            msgBox.Show();
        }

        [Obsolete(message: "此方式已过时, 使用 OnFunc 来控制是否关闭窗体")]
        void abp(string argU = "", string argP = "")
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入管理员账号密码",
                "Hello\r\nWorld"
            );

            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel();

            if (argU.IsNullOrWhiteSpace() == false)
                vm.LoginAccount = argU;

            if (argP.IsNullOrEmpty() == false)
                vm.Password = argP;

            var content = new WPFControls.MessageBoxExtraContent.CcAccountPassword(vm);

            msgBox.ExtraContent = content;

            msgBox.ShowDialog(); // !!! 注意不能直接用ShowDialog的返回结果, 需要用对象的 MessageBoxResult 属性

            if (msgBox.MessageBoxResult == MessageBoxResult.OK)
            {
                var u = content.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel;
                if (u.LoginAccount == "a2222" && u.Password == "2")
                {
                    MessageBox.Show(Util.JsonUtils.SerializeObjectWithFormatted(u));
                }
                else
                {
                    MessageBox.Show("密码错误");
                    // 验证失败了，再次调用 并且 预设好上一次的账号
                    abp(u.LoginAccount, u.Password);
                }
            }
        }

        private void Button_ExtraContent_Password(object sender, RoutedEventArgs e)
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入管理员密码",
                "咨询管理员处理",
                icon: MessageBoxImage.Question,
                onFunc: (target, result) =>
                {
                    var view = target.ExtraContent as WPFControls.MessageBoxExtraContent.CcPassword;
                    var viewModel = view.DataContext as WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel;

                    if (viewModel.Password != "654321")
                    {
                        WPFControls.MessageBox.ShowErrorDialog(owner: target, message: "密码错误!", details: "654321");
                        viewModel.Password_IsFocusSelectAll = true;
                        return false;
                    }

                    return true;
                }
            );

            var vm = new WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel();
            var content = new WPFControls.MessageBoxExtraContent.CcPassword(vm);
            msgBox.ExtraContent = content;
            // !!!!!!!!!! 阻塞方式显示
            msgBox.ShowDialog(); // !!! 注意不能直接用ShowDialog的返回结果, 需要用对象的 MessageBoxResult 属性

            // 继续下面的逻辑
            // 打开界面......
            // if(msgBox.MessageBoxResult == MessageBoxResult.OK)
            // { ... }
        }

        #endregion

        public void Button_Show_OnAction(object sender, RoutedEventArgs e)
        {
            WPFControls.MessageBox.ShowConfirm
            (
                (r) => { MessageBox.Show($"{r} - ShowConfirm"); },
                "确认退出?",
                "OnAction => (r) => { if (r == MessageBoxResult.OK) { MessageBox.Show(\"OK\"); } } "
            );

            WPFControls.MessageBox.ShowQuestion
            (
                (r) => { MessageBox.Show($"{r} - ShowQuestion"); },
                "确认退出?",
                "OnAction => (r) => { if (r == MessageBoxResult.OK) { MessageBox.Show(\"OK\"); } } "
            );

            WPFControls.MessageBox.ShowInformation
            (
                "ShowInformation",
                "OnAction => (r) => { if (r == MessageBoxResult.OK) { MessageBox.Show(\"OK\"); } } ",
                onAction: (r) => { MessageBox.Show($"{r} - ShowInformation"); }
            );

            WPFControls.MessageBox.ShowError
            (
                "ShowError",
                "OnAction => (r) => { if (r == MessageBoxResult.OK) { MessageBox.Show(\"OK\"); } } ",
                onAction: (r) => { MessageBox.Show($"{r} - ShowError"); }
            );

            WPFControls.MessageBox.ShowWarning
            (
                "ShowWarning",
                "OnAction => (r) => { if (r == MessageBoxResult.OK) { MessageBox.Show(\"OK\"); } } ",
                onAction: (r) => { MessageBox.Show($"{r} - ShowWarning"); }
            );
        }

        public void Button_ExtraContent_Password_Show(object sender, RoutedEventArgs e)
        {
            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入管理员密码",
                "咨询管理员处理",
                onFunc: (s, r) =>
                {
                    if (r != MessageBoxResult.OK)
                    {
                        return true; // 关闭窗口
                    }

                    var c0 = s.ExtraContent as WPFControls.MessageBoxExtraContent.CcPassword;
                    var vm0 = c0.ViewModel;
                    if (vm0.Password != "654321")
                    {
                        WPFControls.MessageBox.ShowErrorDialog(s, "密码不等于 654321");
                        vm0.Password_IsFocusSelectAll = true;
                        return false;
                    }

                    return true; // 关闭窗口
                }
            );

            msgBox.FontSize = 40d; // 测试对单个 MessageBox 进行 FontSize 的设置

            // 报错 -- 转换对于 Window 无效。 
            // msgBox.RenderTransform = new ScaleTransform() { ScaleX = 3d, ScaleY = 3d };
            // 原因是 MessageBox 本身就有 RenderTransform 用于启动时的动画

            var viewModel = new WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel();
            var extraContent = new WPFControls.MessageBoxExtraContent.CcPassword(viewModel);
            msgBox.ExtraContent = extraContent;

            msgBox.Show();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            WPFControls.MessageBox.ShowErrorDialog(LongMsg, LongMsg);
        }

        private void Button_FrmTouchKeyboard_Click(object sender, RoutedEventArgs e)
        {


            var msgBox = WPFControls.MessageBox.GetMessageBox4UserDefineCc
            (
                "请输入管理员密码",
                "咨询管理员处理",
                onFunc: (s, r) =>
                {
                    if (r != MessageBoxResult.OK)
                    {
                        return true; // 关闭窗口
                    }

                    var c0 = s.ExtraContent as WPFControls.MessageBoxExtraContent.CcPassword;
                    var vm0 = c0.ViewModel;
                    if (vm0.Password != "654321")
                    {
                        WPFControls.MessageBox.ShowErrorDialog(s, $"密码不等于 654321, 密码等于 {vm0.Password}");
                        vm0.Password_IsFocusSelectAll = true;
                        return false;
                    }

                    return true; // 关闭窗口
                }
            );

            var viewModel = new WPFControls.MessageBoxExtraContent.ViewModels.AccountPasswordViewModel();
            var extraContent = new WPFControls.MessageBoxExtraContent.CcPassword(viewModel);
            msgBox.ExtraContent = extraContent;

            msgBox.Show();

            // start 增加软键盘
            var txtPassword = WPFControlsUtils.FindChildOfType<PasswordBox>(extraContent);
            txtPassword.MouseDoubleClick += (s1, e1) =>
            {
                if (s1 is PasswordBox == false) { return; }

                PasswordBox target = s1 as PasswordBox;

                if (target.Tag == null)
                {
                    Client.Components.FrmTouchKeyboard frmTouchKeyboard = new Client.Components.FrmTouchKeyboard(msgBox);

                    EventHandler<Client.Components.FrmTouchKeyboard.InputEventArgs> Handle_InputResult
                        = new EventHandler<Client.Components.FrmTouchKeyboard.InputEventArgs>((ss, ee) => Client.Components.FrmTouchKeyboard.UpdatePassword(target, ee));

                    frmTouchKeyboard.InputResult += Handle_InputResult;
                    frmTouchKeyboard.Deactivated += (ss, ee) =>
                    {
                        frmTouchKeyboard.HideKeyboard();
                    };

                    frmTouchKeyboard.Show();

                    target.Tag = frmTouchKeyboard;
                }
                else 
                {
                    (target.Tag as Client.Components.FrmTouchKeyboard).Show();
                }
            };
            // end 增加软键盘
        }
    }
}
